\documentclass[a4paper,12pt,twoside,openany]{report}
%
% Praca dyplomowa Mateusza Grzechocińskiego (mateusz.grzechocinski@gmail.com)
% oparta na szablonie stworzonym przez
% dr hav. inż. J. Starzyńskiego (jstar@iem.pw.edu.pl) na podstawie pracy dyplomowej
% mgr. Błażeja Wincenciaka
% Wersja szablonu 3.0 - 10 stycznia 2009
%
\usepackage{polski} 			% język polski
\usepackage[utf8]{inputenc}		% kodowanie plików wejściowych
\usepackage[pdftex]{graphicx}	% obsługa grafiki w PDFie
\usepackage[pdftex]{hyperref}	% obsługa linków w PDFie
\usepackage{tabularx}
\usepackage{array}
\usepackage[polish]{babel}		
\usepackage{subfigure}
\usepackage{amsfonts}
\usepackage{listings}
\usepackage{color}
\usepackage{xcolor}
\usepackage{verbatim}
\usepackage{indentfirst}
\usepackage{booktabs}% ladniejsze tabelki

\renewcommand{\textfraction}{0.1}

% rozmaite polecenia pomocnicze
% gdzie rysunki?
\newcommand{\ImgPath}{./include/img}

% oznaczenie rzeczy do zrobienia/poprawienia
\newcommand{\TODO}{\textbf{\underline{TODO }}}

\def\ang#1{(ang. \textit{#1}\/)}
\def\tp{\tech{WordCounter}}

% Obrazki na koncu rozdzialu...
%\long\def\obrazek#1#2#3{\begin{figure}[htb]
\long\def\obrazek#1#2#3#4{\begin{figure}[!htb]
\begin{center}
\includegraphics[width=#4]{#1}
\end{center}
	\caption{#2}
	\label{#3}
\end{figure}}

\def\rref#1{rys.~\ref{#1}}

% Redefinition of \cleardoublepage. Even pages are left completely blank.
\let\origdoublepage\cleardoublepage
\renewcommand{\cleardoublepage}{%
  \clearpage{\pagestyle{empty}\origdoublepage}}

% wyróżnienie slow kluczowych
\newcommand{\tech}{\texttt}

% na oprawę (1.0cm - 0.7cm)*2 = 0.6cm
% na oprawę (1.1cm - 0.7cm)*2 = 0.8cm
%  oddsidemargin lewy margines na nieparzystych stronach
% evensidemargin lewy margines na parzystych stronach
\def\oprawa{1.05cm}
\addtolength{\oddsidemargin}{\oprawa}
\addtolength{\evensidemargin}{-\oprawa}

% table span multirows
\usepackage{multirow}
\usepackage{enumitem}	% enumitem.pdf
\setlist{listparindent=\parindent, parsep=\parskip} % potrzebuje enumitem

%%%%%%%%%%%%%%% Dodatkowe Pakiety %%%%%%%%%%%%%%%%%
\usepackage{prmag}   % definiuje komendy opieku,nrindeksu, rodzaj pracy, ...

% Listings - JAVA %
\definecolor{light-gray}{gray}{0.985}
\definecolor{dark-gray}{gray}{0.10}
\lstset{language=java,
	basicstyle=\ttfamily\scriptsize,
	breaklines=true,
	keywordstyle=\color{blue},
	stringstyle=\color{red},
	commentstyle=\color{dark-gray}\slshape,
	frame=single,
	backgroundcolor=\color{light-gray},		
	tabsize=3,
	showspaces=false
}

% listings - logi
\lstnewenvironment{logs}{
	\lstset{
		basicstyle=\ttfamily\scriptsize,
		breaklines=true,
		stringstyle=\color{red},
		commentstyle=\color{dark-gray}\slshape,
		frame=single,
		backgroundcolor=\color{light-gray}
}}{}


%%%%%%%%%%%%%%% Strona Tytułowa %%%%%%%%%%%%%%%%%
% To trzeba wypełnić swoimi danymi
\title{System wspierający stosowanie praktyki Ciągłej Integracji}

% autor
\author{Mateusz Grzechociński}
\nrindeksu{197581}

% wstawienie zdjęcia
\zdjecie{\includegraphics[width=3.3cm]{\ImgPath/zdjecie.png}}

\opiekun{dr hab. inż. Jacek Starzyński}
\recenzent{dr inż. Robert Szmurło}
\terminwykonania{11 lipca 2010}

% data złożenia - pokazana na stronie tytułowej
\date{\today}
\rokakademicki{2009/2010}

% zakres pracy
\zakres{\input{./include/tex/zakres.tex}}

\oswiadczenie{\noindent Mateusz Grzechociński  - oświadczam, że niniejszą pracę dyplomową wykonałem samodzielnie i nie naruszyłem niczyich praw autorskich.}
% Podziękowanie - opcjonalne
% \podziekowania{\input{podziekowania.tex}}

\begin{document}
\maketitle

%+++ BEGINNING +++

%-----------------
% Wstęp
%-----------------
\chapter*{Słownik}
\begin{description}
\item{XP} Metodyka programowania ekstremalnego \ang{eXtreme Programming}
\item{ CI } Ciągła Integracja - jedna z praktyk XP
\item{ TDD } programowanie sterowane testami \ang{Test Drive Development}
\item{ YAGNI } Zasada ,,nie będziesz tego potrzebował'' \ang{You ain't
gonna need it}
\item{ CVS } System służący do kontroli wersji plików \ang{Concurrent
Versions System }
\item{ SVN } System służący do kontroli wersji plików \ang{Subversion}
\item{ GG } Gadu--gadu, jeden z najpopularniejszych w Polsce
komunikatorów internetowych
\item{ KMP } Algorytm Knutha--Morrisa--Pratta
\item{ JDK } Środowisko programistyczne Java \ang{Java Development Kit}
\item{ JRE } Środowisko uruchomieniowe Java \ang{Java Runtime Environment}
\item{ JEE } Specyfikacja definiująca standard tworzenia
,,korporacyjnych'' aplikacji opartych o wielowarstwową architekturę
komponentową \ang{Java Enterprise Edition}
\item{ SMTP } Protokół komunikacyjny przekazywania poczty elektronicznej
\ang{Simple Mail Transfer Protocol}
\item{ ORM } Mapowanie obiektowo-relacyjne \ang{Object-relational mapping}
\item{ DAO } Warstwa dostępu do danych \ang{Data access objects}
\item{ GUI } Graficzny interfejs użytkownika \ang{Graphical user interface}
\item{ IoC } Paradygmat zakładający delegowania części odpowiedzialności
za wykonywane czynności na zewnątrz danego komponentu \ang{Inversion of
control}
\item{ DI } Jedna z realizacji IoC polegająca na wyniesieniu kodu
odpowiadającego za tworzenie zależności pomiędzy klasami na zewnątrz, tj
np. do kontenera IoC \ang{Dependency Injection}
\item{ RSS } Rodzina języków służących do przesyłania nagłówków
wiadomości publikowanych na obserwowanych stronach internetowych
\ang{Really Simple Syndication}
\item{ Cron } uniksowy program pozwalający na cykliczne uruchamianie
zadań w oparciu o definicję częstotliwości wywołań opisaną specjalnymi
wyrażeniami
 \item{ API } Interfejs programistyczny aplikacji \ang{Application
Programming Interface}
\end{description}
\chapter{Wstęp}
\section{Wprowadzenie}
Każdego dnia, na całym świecie niezliczona ilość architektów, analityków, programistów i testerów pracuje nad projektami informatycznymi. Owocem ich pracy są aplikacje wspierające człowieka w niemal każdej sferze życia (nauka, praca, rozrywka). Choć w przeważającej większości projekty te są tworzone na zamówienie klienta i to on najczęściej jest ich jedynym użytkownikiem, to każdy z nas mógłby wymienić przynajmniej kilka takich aplikacji, które miały realny wpływ na życie całego świata.

Potężna (na skalę światową) produkcja oprogramowania przyspiesza z roku na rok. Postępująca technologia,  wprowadzane standardy, olbrzymia ilość narzędzi i bibliotek programistycznych dających nowe możliwości sprawia, że firmy zajmujące się produkcją oprogramowania są w stanie zaoferować produkt, którego stworzenie jeszcze kilka lat temu było prawie niemożliwe.

Z biegiem czasu i w ślad za postępem technologicznym podążają również wymagania klienta dotyczące zamawianego produktu. Coraz bardziej skomplikowane procesy biznesowe, wysoki stopień zależności, warunkowe podejmowanie decyzji o danym zachowaniu powodują, że zamawiane projekty są coraz bardziej skomplikowane i wymagają bardzo dobrego zrozumienia pomiędzy klientem, a analitykiem.

Niestety, jak pokazują badania \cite{Chaos}, w ubiegłym roku niemal 44\% projektów oddawanych było ze znacznym opóźnieniem, przekraczało założony budżet lub zawierało niekompletną funkcjonalność. Aż 24\% przeprowadzonych w 2009 roku projektów zakończyło się całkowitym upadkiem. 

Wiedza zdobywana latami przez osoby zajmujące się tworzeniem oprogramowania przerodziła się w dziedzinę nauki jaką jest ,,Inżynieria oprogramowania''. Olbrzymi bagaż doświadczeń jakimi dysponują osoby zajmujące się nią na co dzień zaowocował powstaniem całego katalogu metodyk prowadzenia projektów informatycznych obejmujących najczęściej wszystkie fazy tworzenia produktu, od analizy biznesowej i systemowej, aż po jego wdrożenie.

Inżynieria oprogramowania przez lata wypracowała szereg metodyk, dziś zaliczanych do metodyk ,,ciężkich''. Jedną z nich jest metodyka oparta o tzw. \textbf{model kaskadowy}, w którym zakłada się podział produkcji oprogramowania na  wydzielone etapy, z których każdy to kolejny ,,schodek'' (kaskada). W modelu tym nie można przejść do kolejnej fazy, bez zakończenia poprzedniej, iteracje są bardzo kosztowne, a podział na fazy jest nieelastyczny i nie daje się dopasować do rzeczywistych wymagań. Rzeczywistość coraz dotkliwiej weryfikuje słuszność takiego podejścia. Projekty prowadzone w ten sposób mają zwykle duże opóźnienia, a często kończą się zupełnym upadkiem. 

W 2001 roku odbyło się dwudniowe spotkanie, w którym udział brało wielu znanych i cenionych osób zajmujących się produkcją oprogramowania -- m.in. M.Fowler, K.Beck, W.Cunningham, R.C.Martin. W wyniku tego spotkania, opublikowany został manifest zwinnego podejścia do prowadzenia projektów \cite{AgileManifesto}, w którym w 12 punktach przedstawione są założenia, które mają stanowić alternatywę dla dotychczasowych praktyk. 

W raz z upływem czasu coraz więcej firm zajmujących się produkcją oprogramowania zaczyna brać pod uwagę taki model prowadzenia swoich projektów. Z obserwacji autora pracy wynika, że temat zwinnych praktyk jest też coraz częściej poruszany na różnych konferencjach \cite{agilece,javarsovia} i cieszy się coraz większym zainteresowaniem zarówno wśród programistów jak i osób zajmujących się zarządzaniem projektami. 

Mimo, że zwinne metodyki są dość młode, już można zauważyć, że projekty prowadzone według ich zaleceń są znacznie lepszej jakości i przynoszą korzyść oraz zadowolenie zarówno dla klienta jak i firmy produkującej oprogramowanie. Pośród wielu istniejących metodyk zwinnych, za jedną z pierwszych uważana jest metodyka programowania ekstremalnego - XP \ang{eXtreme programming}\cite{xp}. Pierwszy projekt stworzony zgodnie z jej założeniami powstał już w 1996 roku~\cite{xp}, czyli 5 lat przed opublikowaniem manifestu. Jedną z podstawowych praktyk tej metodyki jest \textbf{ciągła integracja} \ang{,,Continous Integration'', w skrócie ,,CI''}. 

\section{Cel i zakres pracy}
Niniejsza praca podzielona została na dwie części: teoretyczną i praktyczną.

Część teoretyczna ma na celu przedstawienie metodyki XP \ang{eXtreme Programming}, a w szczególności jednej z jej podstawowych praktyk jaką jest \textbf{ciągła integracja}. Omówione tu zostaną główne założenia i dobre praktyki związane z praktyką CI, które znacząco wpływają na jakość pracy zespołu programistów. Przedstawione zostaną czynności jakie należy wykonać, aby wprowadzić praktykę ciągłej integracji i przekonać do niej zespół. W tej części zaprezentowane zostaną przykładowe, istniejące narzędzia wspierające praktykę ciągłej integracji z uwzględnieniem ich wad i zalet.

W ramach niniejszej pracy powstanie również aplikacja, która w łatwy i prosty sposób będzie pomagać zespołowi programistycznemu w praktykowaniu CI. Część praktyczna będzie ściśle związana z omówieniem tego narzędzia. Stworzona zostanie specyfikacja funkcjonalna oraz implementacyjna. Omówiony zostanie proces instalacji oraz typowy przypadek użycia. Przedstawione zostaną nietypowe elementy aplikacji, napotkane problemy oraz ich rozwiązania oraz możliwe wizje rozwoju aplikacji.

\chapter{Metodyka XP}

\section{Wprowadzenie}
Za twórcę paradygmatu programowania ekstremalnego \ang{eXtreme Programming, w skrócie XP} uważany jest Kent Beck. W 1996 roku, jako specjalista od języka Smalltalk został wynajęty do pracy przy projekcie Chrysler Comprehensive Compensation System (C3)~\cite{XPHistory}. Informacje o praktykach, które wdrażał Beck były publikowane i dyskutowane na publicznym Wiki założonym przez Becka i W.Cunninghama -- Portland Pattern Repository~\cite{PortlandPatternRepository}. Obserwacje i doświadczenia zdobyte przez Becka w tamtym czasie w 1999 roku zaowocowały wydaniem przez niego pierwszej książki o XP~\cite{EXExplained}. Projekt C3 został ostatecznie porzucony przez firmę Chrysler w lutym 2000 roku, jednak nowe podejście do programowania pozostało i jak się okazało, zrewolucjonizowało ogólne podejście do wytwarzania oprogramowania.

Głównym celem XP jest rozwój oprogramowania, który ma być sprawny, mniej kosztowny, wolny od błędów, z zachowaniem większej produktywności zespołu, który go wytwarza. XP jest skierowane przede wszystkim do zespołów, które w swoich projektach nie radzą sobie z tradycyjnymi metodykami. XP odnosi się głównie do prowadzenia projektów charakteryzujących się wysokim ryzykiem. W projektach tego typu zwykle nie ma jasno określonych wymagań i specyfikacji. Nikt nie wie, co dokładnie jest do zrobienia i jak końcowy produkt powinien wyglądać~\cite{Beck}.

\section{12 praktyk metodyki XP}
\label{12XP}

Idea metodyki XP polega na synergii kilkunastu praktyk, które znacząco wpływają na jakość wytwarzanego oprogramowania, ale same w sobie mogą być trudne w zastosowaniu. XP ma zadanie wydobyć co najlepsze z tych praktyk i poprzez ich złączenie, zniwelować wady każdej z nich. Główne założenia XP zlokalizowane są wokół 12 praktyk~\cite{xpRules}. Choć samo XP jest dość młode, warto wspomnieć, że część praktyk i wartości, które faworyzuje są obecne w świecie informatyki już od dawna. Dla przykładu, praktyka programowania sterowanego testami była stosowana już w latach 1959-64 przez NASA w projekcie Mercury~\cite{NASAMercury}.

\subsection{Planowanie i scenariusze}
Zbieranie wymagań klienta i planowanie pracy powinno opierać się na tzw scenariuszach~\ang{user stories}. Klient definiuje scenariusze dostarczając jedynie taki zakres informacji, jaki jest niezbędny do zrozumienia danego wymagania. Ważne jest też określenie priorytetu powstania danej funkcjonalności, aby zespół wiedział, jak ważne jest dane wymaganie w kontekście pozostałych elementów aplikacji. Ma to szczególne znaczenie nie tylko dla zespołu, który kieruje się tą informacją podczas planowania kolejnych iteracji, ale też dla klienta, który w szczególnych przypadkach jest w stanie szybko zrezygnować z poszczególnych, mało istotnych wymagań, kierując uwagę zespołu w stronę kluczowych funkcjonalności. 

Scenariusze dostarczone przez klienta biorą czynny udział w procesie powstawania projektu, estymowania kosztów wytworzenia oraz ogólnego zarządzania projektem. Pozwalają w jasny i czytelny dla obu stron zobrazować postęp prac po zakończeniu danej iteracji.

\subsection{Częste wydania}
Dużą wagę przykłada się do tego, aby wytwarzane oprogramowanie prezentowane było klientowi możliwie najczęściej. Produkt powinien być dostarczany w małych, często wydawanych i uaktualnianych wydaniach. Dobrą praktyką jest wydawanie kolejnych wersji aplikacji za każdym razem, gdy pojawia się w niej pewna nowa, zrealizowana w całości funkcjonalność.

Spotkania z klientem powinny odbywać się regularnie i często. Klient, poprzez bardzo częste spotkania i udziały w cyklicznych demonstracjach aplikacji bierze czynny udział w jej tworzeniu. Zgłaszane przez niego uwagi są bardzo szybko wprowadzane, przez co ich koszt jest niższy. Otrzymując gotowy produkt klient wie, że zawiera on dokładnie to czego oczekiwał, a nie to co zostało spisywane tygodniami na papierze. Podejście takie jest też korzystne dla zespołu. Posiada on bowiem świadomość, że to, nad czym obecnie pracuje zostało kilka dni temu ustalone z przedstawicielem klienta i będzie dokładnie tym, czego klient oczekiwał. Częste prezentowanie efektów pracy sprawia, że klient nie może stwierdzić, iż dany wycinek aplikacji zupełnie nie spełnia jego wymagań. Zespół może być pewien, iż wynik jego pracy będzie podlegał w najgorszym przypadku drobnym modyfikacjom, a nie zupełnym przebudowaniem danej funkcjonalności aplikacji. Po każdym spotkaniu obie strony mają świadomość, w którą stronę zmierza projekt, ukończenie jakich funkcjonalności jest w danej chwili najważniejsze i nad czym trzeba skupić szczególną uwagę.

\subsection{Klient jako członek zespołu}
W metodykach zwinnych, a więc również w metodyce XP bardzo ważną rolę pełni klient -- osoba zamawiająca oprogramowanie. Spotkania, podczas których prezentowane są efekty pracy oraz omawiane i uszczegóławiane kolejne funkcjonalności powinny się odbywać możliwie często, np. raz w tygodniu. Pożądana jest sytuacja, w której klient jest w stanie wyznaczyć swojego przedstawiciela, który dokładnie zna specyfikację i ,,wie czego chce''. Specyfikacje tworzone tygodniami przez analityków podczas niezliczonej liczby spotkań z klientem są zwykle albo niedokładne, albo szybko się dezaktualizują. Zawsze można w nich znaleźć niejasne, niedoprecyzowane określenia, a problemy, który wynikają dopiero w fazie implementowania danej funkcjonalności, nie są przewidziane i omówione. Klient (lub przedstawiciel klienta) jest więc dla zespołu kimś bardzo ważnym. Taka osoba powinna być do dyspozycji zespołu cały czas, a spotkania z nim powinny rozwiewać wszelkie wątpliwości. 

\subsection{Wspólna odpowiedzialność}
\label{collectiveownership}
Kod projektu tworzonego zgodnie z XP jest przynależny do całego zespołu i to cały zespół jest za niego odpowiedzialny. Nie dopuszcza się, aby to programista tworzący dany fragment funkcjonalności był jedyną osobą, która ten kod zna i powinna naprawiać w nim ewentualne błędy. Takie podejście daje bardzo duże możliwości rozwojowe całemu zespołowi. Dla przykładu, osoba nie mająca żadnego doświadczenia z językiem SQL, będzie musiała nadrobić ewentualne braki w wiedzy, aby być w stanie rozwiązać problem niewydajnego zapytania bazodanowego. 

Nacisk na wspólną odpowiedzialność za wykonywaną pracę widać w różnych innych aspektach XP, taki jak wspólne planowanie czy też programowanie w parach.

\subsection{Przyjęta metafora dla projektu}
Czas, jaki nowa osoba w projekcie będzie musiała poświęcić na wdrożenia powinien być zredukowany do minimum. Wszystkie osoby zaangażowane w projekt, zarówno po stronie klienta, jak i firmy produkującej oprogramowanie powinny ustalić wspólnie pewien zestaw nazw, skrótów czy pojęć, których będzie używał do wzajemnej komunikacji. Każda taka osoba powinna bez trudu móc opowiedzieć w kilku zdaniach do czego służy dana aplikacja, z jakich elementów się składa oraz jakie zadania biznesowe realizuje. Zespół powinien wypracować konwencję nazewniczą, która będzie jasno określała i modelowała konkretne zadanie biznesowe.

\subsection{Standardy programowania}
W kontekście rozdziału~\ref{collectiveownership} ważne jest, aby cały zespół posiadał dużą wiedzę na temat projektu i poruszał w się biegle po wyprodukowanym kodzie. Między innymi z tego powodu bardzo ważne jest przed rozpoczęciem pracy ustalenie pewnych standardów oraz konwencji nazewniczych dla klas, metod, zmiennych. Konwencja ta powinna być bezwarunkowo stosowana przez wszystkich programistów w zespole, co znacznie ułatwia późniejsze czytanie kodu i jego ewentualne zmiany. Metodyka XP nie narzuca konkretnych konwencji, wywierając jedynie nacisk na to, aby cały zespół daną konwencję stosował.

\subsection{Proste rozwiązania}
Projektując i tworząc oprogramowanie, programiści powinni kierować się zasadą ,,nie będziesz tego potrzebował''~\ang{YAGNI - You ain't gonna need it}~\cite{yagni}, uznając, że najprostsze rozwiązania są zwykle najlepsze. Podczas implementowania każdej nowej funkcjonalności, programista powinien zadać sobie pytanie: ,,czy nie można zrobić tego prościej?''. W praktykowaniu tej zasady bardzo pomaga programowanie sterowane testami opisane w rozdziale~\ref{TDD}, gdzie mając już pewny działający element aplikacji oraz zestaw testów weryfikujących jego poprawność, programista może z dość dużym zaufaniem zmieniać i upraszczać implementacją tak, aby stała się czytelna i zrozumiała.

\subsection{Programowanie w parach}
Jedną z kluczowych praktyk XP jest programowanie w parach \ang{pair programming}. Zadanie do wykonania jest przydzielane dwóm programistom, którzy siedzą obok siebie. Jeden z nich rozpoczyna pisanie testów do funkcjonalności, którą mają razem stworzyć. Drugi, równolegle implementuje dane wymaganie. W pewnym momencie ich praca podlega wzajemnej weryfikacji, zarówno poprzez stworzone testy, jak i przez partnera. Istnieją różne modele pracy w parach. Poza wyżej wspomnianą, niektóre zespoły praktykują ją w ten sposób, że jedna z osób jest niejako właścicielem klawiatury i to ona tworzy kod. Druga osoba pełni rolę nadzorcy i mentora -- zadaje pytania, zwraca uwagę na błędy, udziela wskazówek. Istnieją też różne zdania na temat doboru ludzi. Jedni starają się dobierać osoby o podobnym poziomie wiedzy, aby mogły siebie nawzajem kontrolować. Inni dopierają osoby o dużej wiedzy i doświadczeniu z osobami o krótszym stażu, zapewniając sobie w ten sposób szybki wzrost wiedzy u mniej doświadczonych pracowników. 

Choć często trudno namówić osoby kierujące projektem do zastosowania praktyki programowania w parach, Ci którzy dadzą się przekonać, zwykle tego nie żałują. Osoby takie zwykle podkreślają, że mimo znacznie większego zmęczenia zauważyły, iż stały bardziej produktywne i dużo nauczyły się od partnera~\cite{TDDReview}. Bez względu na przyjęty model, praca w parach, poza oczywistym rozwojem członków zespołu, zwraca uwagę na pewne błędy i niedociągnięcia, których pojedyncza osoba, autor danego wycinka kodu nie byłaby w stanie sam zauważyć. Programowanie w parach zdecydowanie polepsza jakość pracy programistów.

\subsection{Testy}
\label{TDD}
W XP bardzo duże znaczenie mają testy, które powinny powstawać równolegle z rozwojem aplikacji. Testy takie powinny być uruchamiane w sposób automatyczny i możliwie częsty. Architektura systemu nie jest finalnie określona na samym początku i ulega ciągłym przemianom podczas rozwijania aplikacji. Dzięki istniejącym testom, zmiany architektoniczne aplikacji nie powinny powodować niekontrolowanej zmiany jej logiki. Praktyka pisania dużej ilości testów i to przed napisaniem docelowego kodu przyjęła się do tego stopnia, że została wydzielona jako oddzielna praktyka -- programowanie sterowane testami \ang{TDD -- Test Driven Development}.

W dużym skrócie, TDD polega na rozpoczęciu pracy od napisania testu jednostkowego (lub najlepiej zestawu takich testów) sprawdzającego poprawność realizowanej funkcjonalności. Z oczywistych powodów, test taki w swej początkowej fazie zawsze kończy się błędem. Nowoczesne środowiska programistyczne~\ang{IDE - Integrated Development Environment} potrafią uruchomić testy jednostkowe, a ich powodzenie obrazują odpowiednim kolorem   (zielonym oraz czerwonym). W związku z tym, w środowisku programistów pierwszą fazę TDD nazywa się często ,,fazą czerwoną''. Gdy testy są gotowe, przechodzi się do pisania rzeczywistego kodu realizującego zadaną funkcjonalność. Stworzony kod musi spowodować, że testy będą spełnione. Podczas implementacji nie zwraca się jednak uwagi na jakość tworzonego kodu, dążąc tylko to tego, by kod realizował założone cele. Gdy osiągnie się stan, w którym testy zakończą się powodzeniem (,,faza zielona''), można przystąpić do ,,oczyszczania kodu''. 

Zmiana implementacji z zachowaniem jej założeń i działania nazywana jest refaktoryzacją \ang{refactoring} \cite{FowlerRefactoring}. Refaktoryzacja ma zwykle na celu sprawienie, aby kod nie zmieniając swojego zachowania stał się bardziej czytelny, zgodny z ogólnie przyjętymi standardami i wzorcami. W fazie refaktoryzacji, programista powinien uruchamiać napisane wcześniej testy weryfikując w ten sposób na bieżąco, czy kod nadal spełnia wszystkie założenia. Gdy osiągnie się zadowalającą jakość, a wszystkie testy kończą się powodzeniem, można uznać realizację danej funkcjonalności za zakończoną i przystąpić do kolejnej. 

Więcej o metodyce TDD można przeczytać m.in. w książce \cite{TDDByExample} oraz na licznych stronach internetowych, np.~\cite{TDDIntro}.

\subsection{Wydajna praca}
Tygodniowy czas pracy każdego członka zespołu powinien wynosić nie więcej niż 40 godzin. Jak pokazało doświadczenie, zmęczenie i usypiający programiści wnoszą zwykle do wspólnej pracy zespołu więcej złego niż dobrego. 

\subsection{Ciągłe dbanie o jakość}
Robert C. Martin w swojej książce~\cite{cleancode} przywołał zasadę obowiązującą w amerykańskim harcerstwie~\ang{The Boy Scout Rule}, która głosi: \textit{,,Opuszczając miejsce, pozostaw je w stanie lepszym, niż gdy je zastałeś''}. Zasadę tę można bezpośrednio zastosować również w programowaniu. Zgodnie z rozdziałem~\ref{collectiveownership}, każdy z programistów powinien mieć podobną wiedzę o projekcie. Jeśli więc dany członek zespołu spotyka się z kodem, który jego zdaniem wymaga poprawy, będąc np. nieczytelnym, duplikowanym, czy naruszającym ogólnie przyjęte standardy, powinien go bezwzględnie poprawić. 

\subsection{Ciągła integracja}
Ostatnią praktyką, będącą przedmiotem niniejszej pracy jest ciągła integracja, mająca zapewnić, że zespół pracuje na najbardziej aktualnej wersji kodu. Praktyka ta ma za zadanie uchronić zespół przed bardzo kosztownym procesem integrowania dużej liczby zmian stworzonych przez członków zespołu na przestrzeni ostatniej iteracji.

\section{Wady XP}

Niestety, metodyka XP jak i całe zwinne podejście do tworzenia oprogramowania posiada też pewne wady. Z doświadczenia autora pracy wynika, że metodyka ta bywa niebezpieczna w przypadku projektów rozliczanych na zasadach stałej kwoty \ang{fixed price}. W pracy z klientami wymagającymi rozliczania projektów w tej formie trzeba być bardzo czujnym i ostrożnym. Uwzględnienie każdej, nawet najdrobniejszej sugestii klienta może stać się nieopłacalne, bo klient płaci z góry ustaloną kwotę za produkt, a nie za czas jaki zespół poświęcił na jego wytworzenie. W takiej sytuacji terminowe ukończenie tak rozliczanego projektu obarczone jest dużym ryzykiem, a opłacalność całego przedsięwzięcia -- wątpliwa. 

\chapter{Ciągła integracja jako część XP}
\section{Historia}
Praktyka ciągłej integracji została zapoczątkowana i wymyślona przez Martina Fowlera \cite{Fowler}, po czym została włączona przez Kenta Becka jako jeden z filarów metodyki XP.

W 2000 roku Fowler, podczas letniej praktyki pracował w jednej z dużych brytyjskich korporacji działającej w branży elektronicznej. Gdy pewnego dnia był oprowadzany po biurach firmy, jego ówczesny szef przedstawił mu projekt informatyczny, który trwał już kilka lat, a obecnie, od kilku miesięcy był ,,integrowany''. Nikt wówczas nie wiedział i nie potrafił określić, jak długo potrwa scalenie poszczególnych modułów aplikacji, które powstawały zupełnie niezależnie.

Doświadczenie to uzmysłowiło Martinowi Fowlerowi jak długim i nieprzewidywalnym procesem jest integracja każdego projektu. Tak właśnie, w okolicach 2000 roku zrodziła się idea stworzenia praktyki częstej, przewidywalnej i prostej integracji, nazywanej ,,Ciągłą Integracją'', która niedługo później stała się jednym z 12 głównych postulatów metodyki XP~\ref{12XP}.

\section{Teoria i główne założenia}

Praca programisty, który ma wykonać pewną drobną zmianę w systemie, powinna rozpocząć się od pobrania z systemu kontroli wersji~(\cite{Fowler}, rozdział \textit{,,Maintain a Single Source Repository''}) najświeższej wersji kodu \ang{checkout}. Po dokonaniu zmiany, programista tworzy do tej zmiany testy automatyczne, które są uruchamiane podczas procesu budowania aplikacji (kompilacja, tworzenie plików wykonywalnych itp.). Programista buduje cały projekt, weryfikując w ten sposób, czy jego zmiana nie spowodowała błędów w pozostałych testach. Jeśli proces zakończy się sukcesem, można uznać, że zmiana wprowadzona przez programistę nadaje się do umieszczenia w repozytorium kodu.

Przed wprowadzeniem zmiany do systemu kontroli wersji należy ponowne pobrać najświeższą wersję projektu \ang{update} i dostosować swój kod do zmian, które wykonali w międzyczasie inni członkowie zespołu. Programista ponownie powinien uruchomić proces budowania projektu i zweryfikować, czy wszystkie testy zostały zakończyły się sukcesem. Jeśli tak, programista wprowadza swoją zmianę do systemu kontroli wersji \ang{commit}.

Narzędzie wspomagające pracę programistów monitoruje zmiany w systemie kontroli wersji i, jeśli takie nastąpią, przebudowuje projekt uruchamiając test automatyczne. Jakikolwiek problem, który blokuje możliwość poprawnego budowania projektu jest zgłaszany do całego zespołu. Jeśli więc którykolwiek z programistów pomyli się przy wprowadzaniu zmiany, zapomni o jakimś pliku itp. -- problem zostanie wychwycony bardzo szybko.

Powtarzanie powyższych czynności przynajmniej raz dziennie jest już spełnieniem podstawowego założenia praktyki ciągłej integracji, jakim jest wysoka częstotliwość integracji. Sprawienie, że zespół nie będzie przechodził obojętnie wobec niestabilnego kodu w repozytorium jest pełnym dopełnieniem tej praktyki. Zespół powinien móc pochwalić się przynajmniej kilkoma poprawnymi integracjami każdego dnia. Integracje zakończone błędem oczywiście się zdarzają, ale powinny być jak najszybciej naprawiane. 

\section{Praktyki w ciągłej integracji}
\subsection{Jedno repozytorium kodu}
\label{scm}
Wszyscy członkowie zespołu powinni pracować na jednym i tym samym repozytorium kodu. Na rynku dostępnych jest wiele systemów kontroli wersji, ale zdecydowanie najpopularniejszymi są darmowe CVS\cite{CVS} i Subversion\cite{SVN}. To w repozytorium powinien znajdować się najbardziej aktualny kod i to jego stabilność jest wyznacznikiem, czy projekt jest w ,,dobrej kondycji''. Żaden programista nie może się usprawiedliwiać faktem, że na jego osobistym komputerze aplikacja się buduje. Obowiązkiem każdego członka zespołu jest doprowadzenie do sytuacji, że jego zmiana jest wprowadzona do głównego repozytorium kodu, a proces budowania projektu z tych źródeł zakończył się sukcesem.

\subsection{Codzienna synchronizacja z repozytorium}
Im rzadziej programista wprowadza swoje zmiany do repozytorium i synchronizuje się ze zmianami wprowadzonymi przez innych członków zespołu, tym czynności te stają się coraz bardziej skomplikowany, a czas na nie poświęcony znacząco się wydłuża. Częsta integracja ogranicza takie sytuacje do minimum. Osoby pracujące nad tą samą częścią aplikacji miałby mnóstwo pracy, gdyby wspólnie modyfikowały te same pliki, a dopiero po miesiącu próbowały wprowadzić swoje zmiany do repozytorium. Robienie tego możliwie najczęściej eliminuje konflikty, zarówno te w kodzie jak i międzyludzkie. Martin Fowler \cite{Fowler} zaleca, aby synchronizowanie się z repozytorium (wprowadzanie swoich zmian i pobieranie zmian innych) odbywało się \textbf{przynajmniej} raz dziennie. W praktyce powinno się to jednak robić znacznie częściej, bo im częściej zespół integrujemy swoje zmiany, tym mniej powstaje konfliktów i dylematów jak je rozwiązać.

\subsection{Automatyczne budowanie projektu}
W dzisiejszych czasach proces budowania kompletnej i gotowej do działania aplikacji ze źródeł bywa niezwykle skomplikowany. Ponieważ budowanie całego projektu odbywa się nawet kilka razy dziennie, każdy zespół powinien korzystać z narzędzi służących do automatycznego budowania aplikacji. Funkcjonalność budowania złożonych projektów oferują nowoczesne środowiska programistyczne, jednak z doświadczenia autora wynika, że rozwiązanie takie nie sprawdza się w praktyce. W CI bardzo dużą wagę przykłada się do automatyzacji procesu budowania, a to umożliwiają tylko narzędzia takie jak: Make\cite{Make}, Ant\cite{ANT}, Maven2\cite{Maven2}. Z ich pomocą jednym poleceniem można wybudować cały projekt. Wszystkie wymienione narzędzia są otwarte i darmowe.

\subsection{Automatyczne testy}
Podczas budowania projektu, bardzo ważne jest uruchomienie możliwie największej liczby automatycznych testów. To dzięki ich niepowodzeniu niemal natychmiast wykryjemy czyja zmiana i w której części aplikacji spowodowała błąd. Test niewątpliwie pomoże nam ją naprawić. Testy automatyczne pomagają zapewnić odpowiednią jakość wyprodukowanego kodu, ale przede wszystkim uodparniają go na poprawki i zmiany wprowadzane przez programistów w innych częściach aplikacji. 

Odpowiednio przetestowany kod jest podstawą skuteczności działania ciągłej integracji. Testy powinny w jak największym stopniu pokrywać zaimplementowaną funkcjonalność. Szanse, że podczas ciągłej integracji zgłoszony zostanie błąd są wprost proporcjonalne do ilości i jakości napisanych testów. Jeśli więc projekt nie będzie posiadał żadnych testów, wówczas narzędzie do ciągłej integracji może zgłosić zespołowi jedynie problemy z kompilacją projektu. Z doświadczenia autora pracy wynika, że błędy tej kategorii są raczej marginalne, a znakomita większość wszystkich zgłoszonych problemów dotyczy niespełnionych testów lub błędów czasu wykonania (np. brak wymaganej biblioteki).

Praktykę tworzenia dużej ilości testów, pokrywających możliwie największą zaimplementowaną funkcjonalność wspiera sama metodyka XP i TDD. Jeśli zespół stosuje TDD, automatycznie zwiększa skuteczność ciągłej integracji. Należy przy tym pamiętać, że duża ilość, nawet bardzo dobrych testów nie gwarantuje, że aplikacja jest wolna od błędów. Z drugiej jednak strony, nawet najmniejsza ilość testów, uruchamianych z dużą częstotliwością jest lepsza od sytuacji, gdy tych testów nie ma, lub nikt ich nie uruchamia.

\subsection{Dedykowany serwer do CI}
Teoria zakłada, że częsta integracja zapewni, iż każdy programista wprowadzając swoją zmianę do repozytorium nie zdestabilizuje kodu\cite{Fowler}. Niestety, brak dyscypliny ze strony członków zespołu powoduje, że nie zawsze tak się dzieje. Z doświadczeń autora pracy wynika, że często się zdarza, iż programista po zakończeniu implementowania od razu przystępuje do wprowadzania zmian do repozytorium. Zapomina jednocześnie o tym, że najpierw powinien pobrać zmiany wprowadzone przez innych i zweryfikować czy jego kod nadal przechodzi wszystkie testy. Niestabilność kodu po takiej operacji może zostać wykryta stosunkowo późno, np. następnego dnia, gdy inny programista przyjdzie do pracy i będzie próbował wybudować projekt na swoim komputerze. Jeśli problem jest na tyle złożony, że jego rozwiązanie zna tylko osoba, która wprowadziła zmianę, może w skrajnych przypadkach dojść do sytuacji, że inni programiści nie mogą wprowadzać swoich zmian, a praca całego zespołu jest przez jakiś czas wstrzymana.

Wobec powyższego, dobrą praktyką jest, aby mieć pewien wyznacznik, który mówi o aktualnej kondycji kodu. Na wzór jednego, wspólnego systemu kontroli wersji dla całego projektu, tworzy się też osobny, dedykowany serwer, na którym cyklicznie przeprowadza się \textbf{ciągłą integrację}. Na dedykowanym serwerze (dalej nazywanym \textbf{,,maszyną integracyjną''}) uruchomiona jest specjalna aplikacja wpierająca proces ciągłej integracji. Stworzenie przykładowej aplikacji, realizującej to zadanie jest przedmiotem drugiej, praktycznej części niniejszej pracy.

Zadaniem maszyny integracyjnej jest ciągłe monitorowanie zmian pojawiających się w repozytorium kodu i natychmiastowe przebudowywanie projektu jeśli taka zmiana się pojawi. Wówczas, nawet gdy programista zapomni o zintegrowaniu się ze zmianami innych członków zespołu, odpowiednie narzędzie samo zweryfikuje, czy aktualny kod jest stabilny.

Maszyna integracyjna powinna stać się swoistym sędzią i rozstrzygać o aktualnej kondycji kodu. Każdy członek zespołu powinien dążyć do sytuacji, w której jego zmiana powoduje poprawne wybudowanie projektu. Jeśli na maszynie integracyjnej projekt się nie buduje, nie jest akceptowalne tłumaczenie, że \textit{,,na moim komputerze działa''} i należy tę sytuację jak najszybciej naprawić. Martin Fowler w ~\cite{Fowler}, w rozdziale ,,Every Commit Should Build the Mainline on an Integration Machine'' przytacza nawet regułę że programista nie powinien iść do domu, póki na maszynie integracyjnej projekt po jego zmianach nie został wybudowany poprawnie.

Jeśli wprowadzona zmiana zdestabilizowała kod, narzędzie powinno niezwłocznie powiadomić o tym cały zespół.
Najczęściej spotykanym sposobem powiadamiania jest mail wysyłany na adres obejmujący wszystkich programistów zaangażowanych w projekt. W liście opisane jest, która dokładnie zmiana i czyjego autorstwa spowodowała błąd podczas budowania projektu. Dobrą praktyką jest powiadamianie zarówno po niepoprawnym jak i \textbf{poprawnym} wybudowaniu projektu. O ile zasadność pierwszego nie budzi wątpliwości, o tyle wiele osób zastanawia się po co im informacja, że projekt został wybudowany prawidłowo. Z doświadczenia autora pracy wynika, że informacja taka jest przydatna, bowiem zwraca uwagę programisty na fakt, że coś się w projekcie zmieniło oraz, że warto pobrać te zmiany jak najszybciej. W przeciwnym razie, wraz z upływem czasu rośnie ryzyko, że synchronizacja ze zmianami innych członków zespołu będzie problematyczna i zajmie programiście dużo czasu.

Kto powinien naprawić błąd, który pojawił się na maszynie integracyjnej? Zdania są podzielone. Martin Fowler\cite{Fowler} twierdzi, że za poprawne wybudowanie projektu na maszynie integracyjnej odpowiedzialna jest osoba wprowadzająca zmianę. Co jednak jeśli osoba ta jest nieobecna w pracy? Co jeśli dwie osoby jednocześnie wprowadzą zmiany do repozytorium? Czasami nie ma pewności czyja zmiana spowodowała dany błąd. Między innymi dlatego metodyka XP zakłada odpowiedzialność i przynależność do kodu ma cały zespół \ang{collective code ownership}~\cite{CollectiveCodeOwnesrship}. Wynika z tego, że dowolna osoba z zespołu, która zauważy błąd na maszynie integracyjnej może i powinna przystąpić do jego naprawy.

Idea współodpowiedzialności za kod może wydawać się nierozsądna. Wiele problemów może przecież powstać, gdy programista musi czuć się odpowiedzialny za kod, którego nie jest autorem i którego zupełnie nie zna. Metodyka XP stara się jednak omijać takie sytuacje poprzez zasady tworzenia testów jednostkowych do każdej funkcjonalności oraz programowania w parach\cite{XProgrammingPairProgramming}. Zgodnie z XP, każda linijka kodu powinna być tworzona w parach\cite{PairProgramming}. Wówczas, przynajmniej dwie osoby z zespołu mają wiedzę na temat danego elementu aplikacji i mogą wspomóc resztę zespołu w naprawieniu ewentualnego błędu.

W praktyce, każdy projekt i każdy zespół jest inny. Zwykle to osoba, która wprowadziła zmianę jest najlepiej zorientowana i będzie w stanie najszybciej rozwiązać problem. Zdarza się też jednak, że inna osoba z zespołu, posiadająca bardzo duże doświadczenie jest w stanie pomóc i szybko przywrócić stabilność kodu. Zdaniem autora pracy, wprowadzanie sztywnych reguł kto może, a kto nie powinien poprawiać powstające błędy nie ma większego sensu. Zdecydowanie ważniejsze jest natomiast, aby zespół cały czas zwracał baczną uwagę na kondycję projektu na maszynie integracyjnej i w przypadku błędu dążył (wspólnie lub typując osobę odpowiedzialną) do jak najszybszego ustabilizowania kodu. Sytuacje, w których cały zespół pracuje i nikt nie przejmuje się błędami występującymi na maszynie integracyjnej są niedopuszczalne.

Wiele firm i organizacji zajmujących się produkcją oprogramowania ustala cykliczne terminy budowania projektu, które zwykle odbywają się w nocy. Są to tzw. \textit{,,nocne integracje''} \ang{nightly builds}, mające za zadanie zapewnić, że kod obecny w repozytorium jest stabilny, a użytkownicy mają zawsze dostęp do najnowszej wersji oprogramowania. Podejście takie jest szczególnie popularne w przypadku dużych i skomplikowanych projektów, jak np. popularna przeglądarka internetowa Mozilla Firefox\cite{FirefoxNightly} czy odtwarzacz VLC Media Player\cite{VLCNightly}.  

W kontekście jak najszybszego wykrywania destabilizacji kodu, takie podejście nie jest najlepsze, ponieważ wprowadzona zmiana może istnieć w repozytorium nawet cały dzień, zanim ktoś zauważy, że źle ona wpływa na kondycję projektu. Jeśli jednak nocne integracje są jedyną formą integracji w danej organizacji, warto przynajmniej taką formę tej praktyki stosować.

\subsection{Szybka weryfikacja}
Praktyka pokazuje, że maszyna integracyjna powinna sprawdzać repozytorium kodu pod kątem pojawiających się zmian przynajmniej co kilka minut. Interwał powinien być jednocześnie na tyle duży, aby zmieściło się w nim wybudowanie całego projektu i ewentualne powiadomienie uczestników o zaistniałym problemie. Powiadomienie musi być jak najszybsze, aby powstrzymać programistów przed wprowadzaniem kolejnych zmian i skupić ich uwagę nad rozwiązaniem problemu.

Wybudowanie projektu przez maszynę integracyjną powinno być zautomatyzowane, a w jego skład bezwzględnie powinny wchodzić testy weryfikujące poprawność zaimplementowanej funkcjonalności. Duża ilość dobrze napisanych testów jest oczywiście szansą na wykrycie jak największej ilości błędów. Z drugiej jednak strony może znacząco wpłynąć na czas budowania całego projektu. W ciągłej integracji bardzo silny nacisk kładzie się na szybką reakcję na zaistniały problem. Nic tak nie psuje tej koncepcji jak projekt, który buduje się bardzo długo. Jeśli proces budowania będzie zbyt długi, zniechęci to programistów do częstego weryfikowania poprawności swoich zmian. Kent Beck twierdzi, że według metodyki XP cały proces powinien trwać nie dłużej niż 10 minut, ale też odpowiednio długo, aby ,,spokojnie wypić kawę''\cite{Beck}. Z doświadczenia autora pracy wynika, że aplikacja powinna budować się znacznie szybciej niż w 10 minut, tj od 3 do 5 minut. 

Jeśli ilość testów w aplikacji i czas ich wykonywania robi się niebezpiecznie duży, dobrym pomysłem jest stworzenie pewnych konfiguracji zawierających zestaw testów wykonujących się nieco dłużej od pozostałych, które można warunkowo włączać do procesu budowania aplikacji. Narzędzia takie jak Maven umożliwiają stworzenie tzw. \textit{,,profili''} uruchamianych przez specjalny parametr dodawany do polecenia uruchamiania skryptu budującego aplikację. Profil może np. dołączać do aplikacji dodatkowe moduły lub zmieniać konfigurację wtyczki uruchamiającej testy. W takim wypadku maszyna integracyjna w pierwszej kolejności wykonuje zestaw ,,szybkich testów'' (zwykle jednostkowych) i tylko jeśli te się powiodą uruchamiany jest zestaw testów ,,wolniejszych'' (zwykle są to testy integracyjne). Zestaw wolnych testów może się też wykonywać równolegle, na drugiej maszynie integracyjnej.

Warto zwrócić uwagę i włożyć dużo wysiłku w to, aby projekt budował się szybko. Każda minuta o jaką zredukuje się ten proces jest zaoszczędzoną minutą pracy każdego programisty. Praktyka ciągłej integracji zaleca wykonywanie jak najczęstszych synchronizacji z repozytorium, więc sumaryczna ilość zaoszczędzonego w ten sposób czasu może być znaczna. 

\subsection{Integracja na środowisku ,,produkcyjnym''}
Ciągła integracja ma za zadanie jak najszybsze wykrycie błędów, które mogą pojawić się na środowisku produkcyjnym. Skoro więc tworzy się dedykowaną do tego celu maszynę integracyjną, warto zbliżyć jej konfigurację możliwie najbardziej do konfiguracji docelowej. Każda różnica pomiędzy środowiskiem testowym, a produkcyjnym niesie ze sobą potencjalne ryzyko nieujawnionego błędu, który może pojawić się dopiero po wdrożeniu aplikacji.

Podobieństwo konfiguracji dotyczy to zarówno zagadnień sprzętowych jak i programowych.
Warto na maszynie integracyjnej zainstalować taką samą wersję bazy danych czy korzystać z takiego samego systemu operacyjnego, jaki będzie na środowisku docelowym. Warto użyć takiej samej konfiguracji sieciowej i sprzętu jak najbardziej zbliżonego do docelowego. W dzisiejszych czasach, z dużą pomocą przychodzi wirtualizacja, dzięki której możemy symulować np. komunikację z kilkoma klientami naszej aplikacji.

\subsection{Dostępność ostatniej stabilnej wersji}
Człowiek ma naturalną skłonność do dokładnej specyfikacji swoich wymagań wtedy, gdy widzi część docelowej funkcjonalności. Mało kto potrafi z dużym wyprzedzeniem jasno określić czego oczekuje od produktu, określając każdy detal. Metodyki zwinne kładą w dużym stopniu wykorzystują tę ludzką cechę, m.in. poprzez częste kontakty z klientem i prezentowanie mu obecnego stanu aplikacji.

Wobec powyższego, ważne jest, aby w każdym momencie dostęp do aktualnej wersji aplikacji był jak najprostszy. Może ona być wykorzystana do celów demonstracyjnych dla klienta, kierownika projektu czy też szybkiego przetestowania pewnej funkcjonalności.

Dzięki ciągłej integracji zespół może mieć pewność, że istnieje dokładnie jedno wspólne miejsce, w którym można zawsze znaleźć najbardziej aktualną i stabilną wersję aplikacji, a proces jej uaktualniania jest w pełni zautomatyzowany. Maszyna integracyjna poza kompilacją i testowaniem kodu może i powinna odkładać w pewne ustalone miejsce gotowe wersje instalacyjne aplikacji. W przypadku aplikacji uruchamianych na serwerze, w skład ciągłej integracji może z powodzeniem wchodzić wdrażanie najnowszej wersji na serwer. 

Dzięki takiemu rozwiązaniu, nagłe spotkanie z klientem i potrzeba zademonstrowania najbardziej aktualnej wersji aplikacji nie będzie dla zespołu żadnym problemem.

\subsection{Aktualny status projektu}
W ciągłej integracji główny nacisk kładzie się na komunikację. Dzięki takiemu podejściu każda osoba związana z projektem może łatwo zobaczyć aktualny stan projektu. Istniejące narzędzia wspierające ciągłą integrację oferują przejrzyste informacje, statystyku i raporty na temat kondycji projektu. Zespoły posiadają różne sposoby na wizualizację aktualnego stanu projektu. W Internecie dostępne są nawet specjalne lampy \ang{lava lamps} podłączane do portu USB, które świecą w odpowiednich kolorach zależnych od aktualnej kondycji projektu na maszynie przeprowadzającej ciągłą integrację. 

\obrazek{\ImgPath/lava_lamp.png}{,,Lava lamps'' reagujące zmianą koloru na pojawienie się ,,złej'' zmiany~\cite{LavaLampsURL}}{lavaLamps}{.50\textwidth}

\newpage
\section{Korzyści}
Podsumowując, korzyści płynące ze stosowania serwera przeprowadzającego ciągłą integrację to przede wszystkim:
\begin{enumerate}
	\item \textbf{Zredukowane ryzyko} -- w każdym momencie wiadomo, że kod znajdujący się w repozytorium jest zintegrowany, a ryzyko, że zawiera błędy jest zredukowane do minimum. Integracja, która odbywa się po zaimplementowaniu wszystkich modułów aplikacji jest nieprzewidywalna~i nikt tak naprawdę nie wie ile może potrwać. Dzięki ciągłej integracji zawsze wiadomo, na jakim etapie jest projekt, co działa, a co wymaga poprawy.
	\item \textbf{Oszczędność czasu na integrację} -- zintegrowanie się ze zmianami wprowadzonymi przez innych członków zespołu zajmuje dużo mniej czasu, bo zmiany te pochodzą co najwyżej tylko z bieżącego dnia.
	\item \textbf{Eliminacja błędów} -- ciągła integracja nie usunie wszystkich błędów z aplikacji, ale sprawi, że ich znalezienie i wyeliminowanie będzie znacznie szybsze. Ponieważ integracja odbywa się często, istnieje niewiele miejsc, w których należy poszukiwać błędu. Destabilizacja kodu jest automatycznie wykrywana już kilka minut po jej wprowadzeniu. O fakcie tym informowani są wszyscy członkowie zespołu.
	\item \textbf{Stabilność kodu} -- w repozytorium kodu znajduje się zawsze aktualna i możliwie najstabilniejsza wersja aplikacji.
	\item \textbf{Łatwe wdrażanie aplikacji} -- proces wdrażania aplikacji może być dzięki odpowiednim narzędziom w pełni zautomatyzowany. Klient oraz osoby zajmujące się testami funkcjonalnymi mogą mieć pewność, że pracują na najbardziej aktualnej wersji aplikacji.
\end{enumerate}

\newpage
\section{Wdrożenie CI w zespole}
Ciągła integracja jest \textbf{praktyką}, a nie narzędziem. Sukces wprowadzenia jej w zespole w dużej mierze zależy od nastawienia samego zespołu. Jeśli zespół dopiero rozpoczyna pracę nad projektem, zalecane jest, aby stosował ciągłą integrację do testowania i monitorowania już pierwszej wprowadzonej zmiany. Wiele zespołów z początku niechętnie podchodzi do pomysłu stosowania ciągłej integracji, argumentując swoje nastawienie tym, że ,,w dużych projektach CI się nie sprawdza'', a ,,nasz projekt jest na tyle specyficzny, że to na pewno nie będzie działać''\cite{CIAntipatterns}. Konsekwentne i sukcesywne wprowadzanie kolejnych elementów tej praktyki powinno jednak przekonać zespół do słuszności takiego podejścia. Martin Fowler podkreśla \cite{Fowler}, że w przeciwieństwie do niektórych innych kontrowersyjnych praktyk metodyki XP, nie spotkał się jeszcze ze złymi opiniami na temat samej ciągłej integracji.

Pierwszym krokiem jaki należy podjąć jest \textbf{automatyzacja procesu budowania aplikacji}. Cały kod aplikacji musi być umieszczony w repozytorium kodu, a cały projekt musi się budować jednym poleceniem. Warto stworzyć takie skrypty, aby proces budowania aplikacji był możliwie najkrótszy i mógł być w pełni zautomatyzowany.

Kolejny etap to \textbf{automatyczne testy}, które powinny bezwzględnie być \textbf{jednym z etapów budowania projektu} i od ich powodzenia powinien być uzależniony sukces integracji całego projektu. Im więcej testów dobrej jakości, tym szansa na wczesne wykrycie błędów jest większa.

\chapter{Przegląd istniejących rozwiązań}

Choć praktyka ciągłej integracji jest dość młoda, na rynku pojawiło się już wiele narzędzi wspierających zespół w jej stosowaniu. Cechą wspólną wszystkich tych aplikacji jest ich przeznaczenie -- mają śledzić zmiany powstające w projekcie, automatycznie je integrować i w sposób natychmiastowy informować zespół o ewentualnych problemach. 

W niniejszej pracy przedstawione zostaną dwa z obecnie najbardziej znanych i rozpowszechnionych na rynku narzędzi tego typu. Pierwsze z nich, Hudson~\cite{Hudson} to całkowicie darmowy projekt, którego można używać również do pracy z projektami komercyjnymi~\cite{HudsonLicense}. Drugi, Bamboo~\cite{Bamboo}, to komercyjny produkt australijskiej firmy Atlassian~\cite{Atlassian}, która zajmuje się tworzeniem różnego rodzaju narzędzi wspierających codzienną pracę programistów. W kolejnych rozdziałach przedstawione zostaną możliwości, wady oraz zalety obu wymienionych produktów.

\section{Hudson}

Hudson jest darmowym narzędziem stworzonym przez Kohsuke Kawaguchi z firmy Sun Microsystems. Obecnie, po przejęciu Suna, projekt ten jest rozwijany przez firmę Oracle. Istnieje możliwość wykupienia płatnego, komeryjnego wsparcia dla projektu Hudson, świadczonego przez firmę InfraDNA~\cite{InfraDNA} założoną przez Kohsuke Kawaguchi.

Instalacja Hudsona została uproszczona do niezbędnego minimum. Wystarczy ze strony projektu pobrać najnowszą wersję pliku hudson.war, a następnie go uruchomić wydając polecenie \tech{java -jar hudson.war}. W pobranym archiwum dostarczana jest również baza danych, dzięki czemu aplikacja do uruchomienia nie potrzebuje nic więcej, jak tylko środowiska uruchomieniowego Java \ang{Java Runtime Enviroment}.

Warto podkreślić, że Hudsona można zainstalować również poprzez stronę internetową \ang{Java Web Start}~\cite{JNLP}. Jednym kliknięciem na stronie Hudsona~\cite{HudsonJNLP} można zainstalować i uruchomić go na komputerze użytkownika. Niezależnie od wybranego sposobu instalacji, Hudson będzie dostępny pod standardowym adresem \tech{http://[host]:8080}. Ekran startowy został przedstawiony na~\rref{hudsonFirstLook}
\obrazek{\ImgPath/hudson_first_look.png}{Hudson -- ekran startowy}{hudsonFirstLook}{.95\textwidth}

Przed zleceniem Hudsonowi przeprowadzenia pierwszej integracji wybranego projektu, niezbędne jest przeprowadzenie kilku czynności konfiguracyjnych. Hudson wymaga m.in.:

\begin{itemize}
	\item \textbf{wskazania lokalizacji JDK}, \ang{Java Development Kit}, w skład którego wchodzi kompilator języka Java, używany przez Hudsona do kompilacji budowanych projektów 
	\item \textbf{wskazania lokalizacji narzędzi}, których będzie używał do budowania projektu (Ant, Maven). Warto dodać, że w przypadku, gdy na serwerze nie ma jeszcze Anta lub Mavena, Hudson oferuje możliwość automatycznej instalacji obu narzędzi przy pierwszym uruchomieniu integracji.
	\item \textbf{skonfigurowania serwera SMTP}, za pośrednictwem którego Hudson będzie wysyłał powiadomienia mailowe do zdefiniowanej dla projektu grupy odbiorców
	\item \textbf{wskazania lokalizacji klienta systemu kontroli wersji CVS}, dzięki któremu Hudson będzie mógł pobrać aktualne źródła monitorowanego projektu. Konfiguracja ta jest niezbędna tylko w przypadku, gdy kod źródłowy projektu znajduje się w repozytorium CVS. W przypadku repozytorium SVN, Hudson nie wymaga żadnej dodatkowej konfiguracji ze strony użytkownika. Razem z Hudsonem jest bowiem dostarczany odpowiedni klient Subversion, służący do obsługi repozytoriów tego typu.
\end{itemize}

Po przejściu przez etap konfiguracji, Hudson jest gotowy do rozpoczęcia pracy z projektem. Przez dostępny kreator, wystarczy dodać nowe zadanie~\ang{Job}. Po wybraniu typu projektu (Maven2) i podaniu lokalizacji repozytorium kodu, w którym znajduje się projekt należy określić, kiedy Hudson ma wykonać integrację projektu. Na potrzeby testu, Hudson został skonfigurowany tak, aby sprawdzał co jedną minutę, czy w repozytorium kodu nie pojawiły się zmiany. Jeśli Hudson stwierdzi, że coś się zmieniło, dokona aktualizacji kodu i rozpocznie integrację.

Od strony użytkownika, szczególnie przydatny jest ekran startowy \ang{dashboard}, na którym prezentowane są aktualne stany integracji wszystkich monitorowanych projektów. Poza standardową ikoną obrazującą sukces/porażkę ostatniej integracji, warto zwrócić uwagę na dość niekonwencjonalny sposób prezentowania informacji o ogólnej kondycji projektu. W przypadku, gdy większość integracji zakończona jest sukcesem, Hudson przyrównuje ,,klimat'' panujący w takim projekcie do słonecznej pogody~(\rref{hudsonProjectHealth}). Im więcej integracji kończy się niepowodzeniem, tym pogoda staje się coraz bardziej pochmurna, deszczowa, a nawet burzowa!
\obrazek{\ImgPath/hudson_project_health.png}{Hudson -- ogólna kondycja projektu, na podstawie ilości integracji zakończonych sukcesem}{hudsonProjectHealth}{.95\textwidth}

Każdy monitorowany przez Hudsona projekt ma swój dedykowany ekran (\rref{hudsonProjectDashboard}), z poziomu którego można przeglądać historię jego integracji, aktualny status, a także przeprowadzić integrację ,,na żądanie'' (bez względu na obecność zmian w repozytorium kodu). 
\obrazek{\ImgPath/hudson_project_dashboard.png}{Hudson -- ekran projektu}{hudsonProjectDashboard}{.95\textwidth}

Analogicznie do projektu, każda integracja w obrębie danego projektu ma swój dedykowany ekran, którego główną wartością informacyjną jest lista zmian jakie spowodowały wykonanie danej integracji. Bardzo przydatna jest też możliwość śledzenia ,,na żywo'' logów z procesu integracji~(\rref{hudsonBuildLog}), co bardzo pomaga w diagnozowaniu ewentualnych błędów integracji. 
\obrazek{\ImgPath/hudson_build_log.png}{Hudson -- log z procesu integracji}{hudsonBuildLog}{.95\textwidth}

Do zalet Hudsona należy zaliczyć przede wszystkim:
\begin{itemize}
	\item fakt, że jest całkowicie darmowy (płaci się tylko za wsparcie techniczne, jeśli jest taka potrzeba),
	\item łatwość w obsłudze (instalacja, konfiguracja), 
	\item obszerna dokumentacja dostępna na stronie projektu,
	\item ekran prezentujący w jednym miejscu aktualny status wszystkich monitorowanych projektów,
	\item możliwość szybkiej instalacji i nauki poprzez Java Web Start~\cite{JNLP},
	\item niezbędne funkcjonalności dostarczone w standardzie,
	\item duża liczba rozszerzeń,
	\item popularność, duża społeczność użytkowników,
	\item ciągły rozwój projektu.
\end{itemize}

Wskazanie znaczących wad projektu takiego jak Hudson nie jest zadaniem łatwym. Z punktu widzenia autora, jedynie konfiguracja tego narzędzia nie daje zbyt wielu możliwości. W przypadku bardziej wymagających użytkowników i zespołów, poziom konfiguracji jaki oferuje Hudson w standardowej wersji może być niewystarczający. Przeszkadzać może np. brak możliwości zdefiniowania kilku komend Mavena, które powinny być zrealizowane w jednym procesie integracji. Potencjalnym problemem może być też fakt, że część parametrów, jak np. czas jaki Hudson czeka od wykrycia zmiany do wykonania integracji definiuje się globalnie dla wszystkich zdefiniowanych zadań. Ponadto, w standardowej wersji Hudson po zakończeniu integracji jest w stanie powiadomić zainteresowane osoby ,,tylko'' przez pocztę e-mail oraz kanały RSS. Brakuje możliwości informowania przez komunikatory internetowe. 

Warto jednak podkreślić, że do Hudsona powstała już bogata kolekcja rozszerzeń~\ang{plugin}~\cite{HudsonPlugins}. W przypadku, gdy czegoś w tym narzędziu brakuje, warto sprawdzić, czy nie powstało już odpowiednie rozszerzenie, które wystarczy zainstalować, aby otrzymać pożądaną funkcjonalność.

Podsumowując, siłą Hudsona jest przede wszystkim to, że jest darmowy i~bardzo funkcjonalny, a przy tym niesamowicie prosty w obsłudze. Czas wdrożenia tego narzędzia jest skrócony do absolutnego minimum. Przy założeniu, że na docelowym serwerze dostępny jest już Maven, JDK oraz osiągalny jest serwer SMTP, wdrożenie Hudsona jest zaskakująco szybkie. Instalacja, konfiguracja i dodanie pierwszego projektu do monitorowania zajmuje jedyne 15 minut! W tak krótkim czasie zespół może otrzymać darmowe narzędzie, które (w tym przypadku) maksymalnie po jednej minucie od dodania ,,wadliwego'' kodu do repozytorium wykryje błąd integracji i powiadomi o tym zespół. Osoba, która zmianę wprowadziła nie będzie mogła twierdzić, że na jej komputerze projekt buduje się poprawnie i nie zamierza niczego poprawiać. Od tej chwili jedynym wyznacznikiem kondycji projektu będzie Hudson. 

Hudson wydaje się być obecnie bezkonkurencyjny na rynku \textbf{darmowych} narzędzi do ciągłej integracji i choć brakuje mu jeszcze sporo do narzędzi komercyjnych, to fakt, że jest darmowy sprawia, iż zdecydowanie warto wziąć go pod uwagę podczas wdrażania automatycznej ciągłej integracji w zespole. 

\section{Atlassian Bamboo}
\label{atlassianbamboochapter} 

Australijska firma Atlassian~\cite{Atlassian} znana jest przede wszystkim z bardzo popularnego narzędzia do śledzenia błędów w projekcie \ang{bugtracker} jakim jest Jira~\cite{Jira}. W ofercie posiada jednak wiele innych produktów i narzędzi, których głównym celem jest wspieranie pracy zespołów zajmujących się wytwarzaniem oprogramowania. Dla obszaru ciągłej integracji Atlassian proponuje Bamboo.

W porównaniu z Hudsonem, już sama strona produktu i jego prezentacja dają znać, że jest to narzędzie komercyjne i profesjonalne. Producent umożliwia pobranie w pełni funkcjonalnej wersji Bamboo i używanie jej za darmo przez 30 dni. Do wyboru jest wersja samodzielna \ang{standalone} (z wbudowanym serwerem) oraz archiwum \tech{war}, gotowe do umieszczenia na przygotowanym przez użytkownika serwerze. Podobnie jak w przypadku Hudsona, Bamboo domyślnie korzysta z własnej bazy danych, dostarczonej razem z produktem.

W celach testowych wybrano wersję samodzielną. Po ściągnięciu pliku (ok. 80MB) okazuje się, że instalacja Bamboo jest równie prosta jak Hudsona, choć w niczym nie przypomina instalacji programu bazującego na JDK (dzięki dołączonemu instalatorowi). Wersja standalone instaluje się w środowisku Windows jako usługa, którą należy uruchomić. Bamboo jest standardowo dostępne pod adresem \tech{http://[host]:8085}. Proces konfiguracji Bamboo jest nieco bardziej rozbudowany, choć nie traci przy tym na ergonomii. Do dyspozycji jest szybka instalacja opartą o wbudowaną bazę danych oraz instalacja użytkownika, w której można zdefiniować wszystkie początkowe ustawienia według własnych potrzeb, a także wybrać własną bazę danych, z której korzystać ma Bamboo. Po wybraniu pierwszej opcję i krótkiej chwili, w której Bamboo się konfiguruje, użytkownik może dodać już pierwszy projekt do monitorowania. W nomenklaturze Bamboo, projekt podlegający monitorowaniu to ,,plan''.

Na uwagę zasługuje bardzo przyjazny kreator, który w kilku krokach prowadzi przez proces tworzenia planu. Już na tym etapie widać, że Bamboo jest narzędziem dopracowanym w najmniejszym szczególe. Klient SVN i CVS dostarczany jest w standardzie. Definicję sprawdzania zmian w repozytorium kodu można definiować na wiele różnych sposobów. JDK, wykorzystywane podczas budowania projektu zostało wykryte automatycznie na podstawie zmiennej środowiskowej \tech{JAVA\_HOME}. Warto zauważyć, że nie udało się to z Mavenem. Mimo iż w systemie istnieje zmienna środowiskowa \tech{M2\_HOME}, Bamboo wymuszało podanie pełnej lokalizacji katalogu z Mavenem. Hudson zachowywał się podobnie, ale oferował ponadto automatyczną instalację Mavena.

Na~\rref{BambooDashboard} zaprezentowany został ekran Bamboo prezentujący aktualną kondycją monitorowanych projektów.
\obrazek{\ImgPath/bamboo_dashboard.png}{Bamboo -- ekran startowy}{BambooDashboard}{.95\textwidth}

Bamboo ogranizuje nawigację po planach i poszczególnych integracjach w niemal identyczny sposób, jak Hudson. Każdy plan posiada swoją stronę, na której prezentowany jest status ostatnio wykonanej integracji. Ponadto użytkownik widzi wykres przedstawiający długość trwania poszczególnych integracji. Gdy projekt, jest budowany przy pomocy Mavena, Bamboo potrafi przeanalizować ile testów zostało uruchomionych podczas integracji oraz które zakończyły się błędem. Przeglądanie związanych z tym statystyk czy raportów nie sprawia żadnych problemów.

Na stronie planu Bamboo prezentuje też ogólną kondycję projektu. W przeciwieństwie do Hudsona, jest to zwykła procentowa wartość obrazująca ile z ostatnich 25 integracji zakończyło się powodzeniem.

\obrazek{\ImgPath/bamboo_plan.png}{Bamboo -- ekran planu}{BambooPlan}{.95\textwidth}

Bamboo jest produktem komercyjnym, co w przekonaniu autora pracy jest zaletą tego produktu. Aplikacja sprawia wrażenie bardzo stabilnej i dopracowanej w najmniejszym szczególe. Oferuje wszystko to co Hudson, dostarczając wszystkie funkcjonalności niezbędne do spełnienia stawianych mu celów. Na uwagę zasługuje dużo przyjemniejszy i bardziej dopracowany interfejs użytkownika oraz liczne ,,kreatory'', które w kilku prostych krokach umożliwiają użytkownikowi wykonanie trudniejszych czynności, jak np. definiowanie nowego planu. Bardzo przydatna jest funkcjonalność umożliwiająca stworzenie planu na podstawie już istniejącego. 

Jedyna wada funkcjonalna jaką warto wskazać, to brak możliwości definiowania kilku komend Mavena w jednym planie. Jest to szczególnie przydatne przy tworzeniu planu mającego za zadanie wydanie oficjalnej, stabilnej wersji aplikacji przy użyciu \tech{maven-release-plugin}~\cite{maven-release-plugin}. Wówczas należy dla całego projektu wykonać najpierw polecenie \tech{mvn release:prepare}, a później \tech{mvn release:perform}. Bamboo tego niestety nie umożliwia. Oferuje w zamian tzw ,,plany zależne'', czyli warunkowe wykonanie planu, tylko gdy inny, zdefiniowany plan został zakończony sukcesem. W tym konkretnym przypadku (release aplikacji) nie jest to rozwiązanie w pełni satysfakcjonujące.

Warto też wspomnieć o bardzo dobrej integracji Bamboo z pozostałymi narzędziami stworzonymi przez Atlassian. Dla przykładu, gdy programista naprawia błąd o sygnaturze "PROJEKT-123" i w komentarzu do wprowadzanej zmiany wpisze ten numer, Bamboo automatycznie stworzy odnośnik, po kliknięciu którego będzie można od razu przejść do opisu błędu w Jira. Integracja tych systemów jest dwustronna. Przeglądając opis błędu w Jira można wybrać zakładkę "Bamboo builds" i zobaczyć, w której dokładnie integracji ta zmiana naprawiająca błąd została zauważona i zintegrowana przez Bamboo.

Bamboo jest produktem komercyjnym, ale warto zauważyć, że zgodnie z polityką firmy Atlassian, wszystkie jej produkty są dostępne do zastosowań w projektach open source zupełnie za darmo~\cite{atlassianfreeforopensource}. Jeśli więc szukamy narzędzia do ciągłej integracji, które będzie wspierało proces tworzenia projektu o otwartym kodzie źródłowym, Bamboo nadaje się do tego celu znakomicie i jest w takiej sytuacji darmowe.

\chapter{BuildCity -- specyfikacja funkcjonalna}
W ramach niniejszej pracy zaprojektowane i zaimplementowane będzie narzędzie wpierające praktykę CI.
Nazwa projektu to \textbf{BuildCity}. Narzędzie będzie aplikacją internetową dostępną poprzez najpopularniejsze obecnie przeglądarki internetowe. Do jej obsługi nie będzie potrzebne żadne dodatkowe oprogramowanie. 

Głównym założeniem funkcjonalnym jest sprawowanie kontroli nad zdefiniowanymi przez użytkowników projektami. Kontrola ta ma podlegać wszystkim zasadom głoszonym przez praktykę CI. W związku z tym, przyjęto założenia funkcjonalne opisane w dalszej części rozdziału.

\section{Definiowanie planów}
Warunkiem koniecznym do pracy BuildCity są tzw ,,plany''. Plan zawiera w sobie informację o projekcie, którego dotyczy, adres URL do repozytorium kodu, które ma być monitorowane oraz informację o tym jak i wskutek jakiego zdarzenia projekt powinien zostać poddany integracji. W skład definicji planu wchodzi też lista osób zainteresowanych rozwojem projektu, które powinny zostać powiadomione o zakończeniu (poprawnym lub błędnym) każdej przeprowadzanej integracji danego projektu. Sposób powiadamiania (e-mail lub komunikator) powinien również zawierać się w definicji każdego planu.

Definiowanie nowego planu będzie jedną z kluczowych funkcjonalności. Cały proces definiowania nowego planu będzie możliwy do zrealizowania z poziomu interfejsu użytkownika.
Osoba definiująca nowy plan będzie zobligowana do podania następujących parametrów:

\begin{enumerate}
	\item \textbf{Definicja projektu} --  podanie nazwy projektu jaka będzie widoczna w BuildCity
	\item \textbf{Lokalizacja repozytorium kodu} --  adres URL do repozytorium SVN, w którym znajduje się kod projektu. 
	\item \textbf{Definicja wzbudzenia procesu integracji} -- użytkownik będzie musiał określić, jakie zdarzenie musi zaistnieć, aby zdefiniowany w poprzednim kroku kod został zintegrowany. Zakłada się tutaj, że użytkownik poda wyrażenie ,,cron''~\cite{quartzcron}, a system będzie według niego sprawdzał czy w monitorowanym kodzie pojawiły się zmiany. 
	\item \textbf{Sposób budowania projektu} -- określenie komendy narzędzia Maven, która ma być uruchomiona w procesie integracji.
	\item \textbf{Powiadomienia} -- zdefiniowanie adresów e-mailowych lub numerów komunikatora Gadu-Gadu, na które będą wysłane powiadomienia o przeprowadzeniu każdej integracji danego projektu, wraz z podaniem statusu jej zakończenia. 
\end{enumerate}
 
\section{Przeglądarka aktywności planów}
Każdy plan jest tylko stałą definicją zbierającą kluczowe informacje niezbędne do obsługi danego projektu przez BuildCity. Poszczególne integracje jakie będą się odbywać nazywane będą ,,aktywnościami planów''. Każdy plan będzie więc zawierał listę swoich aktywności, których historię będzie można przeglądać. Każda aktywność będzie ze sobą niosła następujące informacje: 
	\begin{enumerate}
		\item Unikalny identyfikator składający się z klucza zdefiniowanego dla projektu oraz numeru (np. MOJPROJEKT-321),
		\item Status zakończenia,
		\item Zmiana w projekcie, która spowodowała daną integrację. Prezentowana będzie lista autorów, komentarze do zmiany oraz lista zmienionych plików. Dzięki temu w bardzo szybki sposób będzie można wytypować, który z członków zespołu jest odpowiedzialny za wprowadzenie zmiany, która zdestabilizowała projekt,
		\item Przeglądarka logów z procesu budowania (integracji) projektu. Funkcjonalność ta będzie szczególna przydatna, gdy proces integracji zakończył się niepowodzeniem.
	\end{enumerate} 

\section{Moduł powiadomień}
O zakończeniu każdej aktywności, Buildcity będzie powiadamiało zdefiniowane dla danego projektu osoby. Zakłada się dwa sposoby powiadomień
\begin{enumerate}
		\item komunikator internetowy,
		\item e-mail.
\end{enumerate}

W powiadomieniu będzie znajdować się informacja, który projekt został zintegrowany i z jakim skutkiem. W przypadku powiadomień e-mailowych, podawana będzie też lista zmian, wraz z autorami i ich komentarzami. 

Ponadto, BuildCity dla każdego monitorowanego projektu będzie udostępniać kanał RSS, który będzie mógł być subskrybowany przez osoby zainteresowane aktywnością w projekcie.

\section{Obsługa komunikatora internetowego}
Nieobecną w innych narzędziach wspierających CI funkcjonalnością będzie bot najpopularniejszego w Polsce komunikatora -- Gadu-Gadu. W chwili uruchomienia aplikacji bot będzie osiągalny pod specjalnym numerem Gadu-Gadu. Bot Gadu-Gadu w BuildCity będzie pełnił dwie role:
\begin{itemize}
	\item powiadamianie zdefiniowanych dla projektu numerów Gadu-Gadu o zakończonej integracji,
	\item nasłuchiwanie komend od użytkowników. W początkowej wersji zakłada się, że istniała będzie jedna komenda pozwalająca na bezwarunkowe uruchomienie integracji wybranego projektu.
\end{itemize}

\chapter{BuildCity -- specyfikacja implementacyjna}

Aplikacja to typowa aplikacja internetowa napisana w języku Java w oparciu o standard Java Enterprise Edition~\cite{specJEE}. BuildCity jest dystrybuowane jako plik *.war gotowy do wdrożenia na dowolnym kontenerze serwletów lub serwerze aplikacyjnym zgodnym z najpopularniejszą obecnie wersją JEE -- 5.0.

\section{Architektura}
Aplikacja BuildCity jest stworzona w oparciu o architekturę wielowarstwową. Poniżej przedstawiono poszczególne warstwy aplikacji, poczynając od ,,najniższej'':

\begin{enumerate}
	  \item model domenowy i warstwa mapowania obiektowo-relacyjnego \ang{ORM -- Object Relational Mapping},
	  \item warstwa dostępu do danych \ang{DAO -- Data Access Objects},
	  \item warstwa transakcyjnych usług biznesowych \ang{Service Layer},
	  \item warstwa graficznego interfejsu użytkownika \ang{GUI -- Graphical User Interface}.
\end{enumerate}

Na \rref{buildcityArchitecture} przedstawiony został diagram wewnętrznej architektury, prezentujący zależność pomiędzy poszczególnymi modułami aplikacji. 

\obrazek{\ImgPath/buildcity_architecture.png}{BuildCity -- diagram architektury}{buildcityArchitecture}{.95\textwidth}

\section{Technologie}

Aplikacja BuildCity jest docelowo uruchamiana w kontenerze serwletów Apache Tomcat 6, jednak zgodność aplikacji ze specyfikacją JEE 5 powinna pozwolić na bezproblemowe i natychmiastowe przeniesienie aplikacji na inny, zgodny z tą specyfikacją serwer (np. Jetty, Glassfish, JBoss etc.)

Do stworzenia aplikacji BuildCity użyto następującego stosu technologicznego:
\begin{itemize}
	  \item \textbf{Spring Framework 2.5}~\cite{spring} -- wsparcie w tworzeniu transakcyjnych usług, wstrzykiwanie zależności do obiektów (kontener IOC \ang{Inversion of control}), wysyłka maili,
	  \item \textbf{Hibernate 3}~\cite{hibernate} -- implementacja standardu JPA 1.0 i warstwa mapowania obiektowo-relacyjnego,
	  \item \textbf{Quartz 1.6}~\cite{quartz} -- jako silnik do tworzenia procesów cyklicznych,
  	  \item \textbf{SVNKit 1.1}~\cite{svnkit} -- jako API SVN dla języka Java,
  	  \item \textbf{Maven Invoker 2.0.11}~\cite{MavenInvoker} -- jako wbudowany \ang{embedded} silnik Mavena. Dzięki temu rozwiązaniu użytkownik BuildCity nie jest zmuszony do podawania ścieżki do Mavena na serwerze, na którym zainstalowana będzie aplikacja,
  	  \item \textbf{jggapi 1.6}~\cite{jggapi} -- jako implementacja protokołu GG dla języka Java,
  	  \item \textbf{ROME 1.0}~\cite{rome} -- jako silnik do tworzenia kanałów RSS,
	  \item \textbf{Apache Velocity 1.6}~\cite{velocity} -- jako silnik do obsługi szablonów powiadomień: e-mail, gg, RSS,
   	  \item \textbf{charts4j 1.2}~\cite{charts4j} -- jako biblioteka udostępniające API do tworzenia gotowego URL'a dla Google Charts API, służącego do tworzenia wykresów,
  	  \item	\textbf{Java Server Faces 1.2}~\cite{jsf} -- jako szkielet wpierający tworzenie interfejsu użytkownika,
	  \item \textbf{JBoss RichFaces 3.3}~\cite{richfaces} -- jako biblioteka gotowych komponentów do tworzenia graficznego interfejsu użytkownika (panele, tabele, obsługa technologi AJAX).
\end{itemize}

Wszystkie powyższe biblioteki są popularne i powszechnie używane w aplikacjach tworzonych w języku Java. Ich licencje pozwalają na wykorzystanie ich w niniejszej pracy. 

\section{Moduły}

BuildCity podzielone jest na kilka modułów (w nomenklaturze Mavena -- ,,artefaktów''), z których każdy odpowiada za pewną funkcjonalność. Moduły zostały wydzielone w taki sposób, aby grupowały i separowały pewne logiczne całości aplikacji oraz aby zależności pomiędzy nimi były możliwie najmniejsze, co znacznie ułatwia późniejszy rozwój aplikacji.

W BuildCity można wyróżnić następujące moduły:
\begin{itemize}
	\item buildcity-builder-maven2
	\item buildcity-charts
	\item buildcity-core
	\item buildcity-gg
	\item buildcity-notifier-gg
	\item buildcity-notifier-mail
	\item buildcity-notifier-rss
	\item buildcity-scheduler
	\item buildcity-scm
	\item buildcity-web
\end{itemize}

Podstawowym modułem aplikacji jest \textbf{buildcity-core}, zawierający model domenowy oraz klasy umożliwiające przeprowadzanie operacji bazodanowych na obiektach domenowych. 

Za monitorowanie zmian w obserwowanych projektach odpowiada moduł \textbf{buildcity-scheduler}. Klasy zawierające się w tym module cyklicznie (zgodne z definicją podaną przez użytkownika) uruchamiają proces składający się kilku etapów, za których realizację odpowiadają pozostałe moduły aplikacji. 

Komunikację z repozytorium SVN realizuje \textbf{buildcity-scm}. To dzięki klasom w nim się znajdującym BuildCity jest w stanie sprawdzić, czy w repozytorium pojawiły się jakieś zmiany, pobrać ich listę wraz z komentarzami ich autorów oraz zaktualizować kopię roboczą. Ponieważ całą komunikacja jest udostępniona aplikacji poprzez generyczny interfejs, moduł ten jest też potencjalnym punktem rozszerzeń, np. o obsługę repozytorium CVS. 

Zadaniem modułu \textbf{buildcity-builder-maven2} jest wybudowanie projektu przy pomocy Mavena i zwrócenie informacji o statusie w jakim ten proces się zakończył. 

BuildCity oferuje możliwość powiadamiania o zakończonej integracji zdefiniowanej listy użytkowników. Powiadomienia mogą być realizowane poprzez różne kanały: komunikator Gadu-Gadu, e-mail, kanał RSS. Powyższa funkcjonalność jest realizowana przez moduły: \textbf{buildcity-notifier-gg}, \textbf{buildcity-notifier-mail}, \textbf{buildcity-notifier-rss}. 

Moduł powiadomień przez komunikator Gadu-Gadu korzysta ponadto z \textbf{buildcity-gg}, którego zadaniem jest opakowanie całej komunikacji z serwerami Gadu-Gadu i udostępnienie odpowiedniego interfejsu programistycznego \ang{API -- Application Programming Interface}. Ponadto, \textbf{buildcity-gg} odpowiada za obsługę bota i nasłuchiwanie i realizację komend zleconych przez użytkowników (np. żądanie przeprowadzenia integracji wybranego projektu). 

Cały interfejs użytkownika dostępny przez przeglądarkę internetową zawarty jest w \textbf{buildcity-web}. Ostatnim modułem jest \textbf{buildcity-charts} odpowiadający za generowanie wykresów przy użyciu Google Charts API i ukrycie całej związanej z tym logiki za łatwym do poznania interfejsem.

\subsection{Testy i programowanie sterowane testami}

Każdy z w/w modułów posiada zestaw testów jednostkowych i integracyjnych, które uruchamiane są przy każdej kompilacji projektu. W chwili ukończenia prac nad BuildCity w projekcie tym znajdowało się 58 testów na bieżąco monitorujących poprawność poszczególnych funkcjonalności. 

Część funkcjonalności projektu BuildCity zostało zrealizowanych w oparciu o metodykę programowania sterowanego testami \ang{TDD -- Test Driven Development}. 

\section{Diagramy klas}

W niniejszym rozdziale przedstawione zostały techniczne aspekty wybranych elementów systemu. Omówiony został sposób zaimplementowania poszczególnych funkcjonalności z naciskiem na zastosowane wzorce projektowe. Dla lepszego zobrazowania dostarczone zostały również diagramy klas.

\subsection{Strategie integracji}

BuildCity przeprowadza integrację monitorowanego projektu w oparciu o przechowywaną na lokalnym dysku kopię roboczą \ang{working copy}, pobraną i uaktualnianą podczas wykrycia każdej zmiany w zdalnym repozytorium kodu. Lokalizację kopii można określić w konfiguracji planu. 

W typowym i najpopularniejszym scenariuszu, przed rozpoczęciem każdej integracji BuildCity sprawdza, czy kopia robocza istnieje w podanej lokalizacji, uaktualnia ją i rozpoczyna integrację. Może się jednak zdarzyć, że kopia robocza nie istnieje w podanej lokalizacji lub jest już aktualna i nie wymaga odświeżania. W pierwszym przypadku, gdy np. jest to pierwsza integracja danego projektu, wymagane jest  pobranie najnowszej wersji kodu z repozytorium. W drugim przypadku, gdy w repozytorium nie pojawiły się żadne zmiany, a kopia robocza jest aktualna - integracja nie musi być przeprowadzana. 

W opisu powyższych scenariuszy jasno wynika, iż istnieją 3 strategie przeprowadzania integracji:
\begin{itemize}
\item{Kopia robocza nie istnieje}
\item{Kopia robocza istnieje, ale jest nieaktualna}
\item{Kopia robocza istnieje i jest aktualna}
\end{itemize}
Każda z w/w strategii pociąga za sobą określone zachowanie BuildCity, szereg czynności jakie należy podejmować tylko w określonym przypadku.

Tego typu wymaganie można zaimplementować w oparciu o szereg instrukcji warunkowych, rozpatrujących wszystkie możliwe przypadki jakie mogą wystąpić w realnym środowisku. Taka implementacja prowadzi jednak zwykle do powstania nieczytelnego, skomplikowanego i trudnego w utrzymaniu kodu. Problem narasta, gdy pojawiają się nowe warunki, które muszą być spełnione, aby integracja została przeprowadzona w określony sposób. 

Wobec powyższego, wymaganie to zostało zaimplementowane przy użyciu jednego z najbardziej znanych wzorców projektowych -- wzorca strategii~\cite{Kerievsky} \ang{Strategy Pattern}. Wzorzec ten zakłada utworzenie jednego interfejsu oraz szeregu implementacji tego interfejsu odpowiadających poszczególnym strategiom działania. O wyborze strategii decyduje zwykle oddzielna klasa, nazywana ,,kontekstem''.


W BuildCity, procesem integracji zarządza moduł \textbf{buildcity-scheduler}. Powstała w nim abstrakcyjna klasa \tech{BuildStrategy}, której metoda~\ref{BuildStrategyExecute} jest używana do przeprowadzania integracji. Jest to jednak tylko szablon umożliwiający poszczególnym strategiom wykonanie odpowiednich czynności, przed, w trakcie oraz po integracji.

\lstinputlisting[caption={Metoda szablonowa realizująca integrację},  label=BuildStrategyExecute]{include/src/execute.java}

Za realizację trzech w/w strategii odpowiadają klasy dziedziczące po \tech{BuildStrategy} i implementujące trzy abstrakcyjne metody. Klasami tymi są:
\begin{itemize}
\item{\tech{FreshBuildStrategy}}
\item{\tech{CodeChangedBuildStrategy}}
\item{\tech{BuildNotRequiredStrategy}}
\end{itemize}
 
Powiązania pomiędzy klasami zostały przedstawione na diagramie~\rref{UMLCDBuildStrategies} 

\obrazek{\ImgPath/uml_cd_build_strategies.png}{Strategie działania BuildCity wobec integrowanego projektu}{UMLCDBuildStrategies}{.95\textwidth}
\newpage

Za wybór strategii odpowiada klasa \tech{BuildJob} i jej metoda~\ref{chooseStrategy}.

\lstinputlisting[caption={Metoda odpowiedzialna za wybór strategii integracji},  label=chooseStrategy]{include/src/chooseStrategy.java}

Warto zauważyć, że strategia ,,świeżej integracji'' wybierana jest w dwóch przypadkach: gdy kopia robocza nie istnieje lub administrator żąda, aby każda integracja była przeprowadzana na nowej, ,,świeżej'' kopii roboczej pobieranej tuż przed każdą integracją.

Strategia ,,świeżej integracji'' zakłada usunięcie (o ile istnieje) kopii roboczej, pobranie najświeższej wersji, uruchomienie integracji oraz powiadomienie zainteresowanych osób. Realizacja została przedstawiona na listingu~\ref{freshBuildStrategy}

\lstinputlisting[caption={Strategia ,,świeżej'' integracji},  label=freshBuildStrategy]{include/src/freshBuildStrategy.java} 

W przypadku, gdy kopia robocza istnieje, ale wymaga aktualizacji, odpowiedzialność przejmuje klasa \tech{CodeChangedBuildStrategy}~\ref{codeChangedStrategy}.

\lstinputlisting[caption={Strategia, gdy kopia robocza wymaga aktualizacji},  label=codeChangedStrategy]{include/src/codeChangedStrategy.java} 

Strategia zakłada zaktualizowanie istniejącej kopii roboczej oraz przeprowadzenie integracji. W przeciwieństwie do poprzedniej strategii, kopia robocza nie jest usuwana i zastępowana nową, a jedynie aktualizowana.
 
Najbardziej trywialną implementacją jest strategia wybierana, gdy kopia robocza istnieje i jest aktualna~\ref{DoNothingStrategy}. Wówczas BuildCity nie podejmuje żadnych czynności, bowiem nie ma potrzeby przeprowadzania integracji kodu, który nie uległ zmianie.

\lstinputlisting[caption={Strategia dla aktualnej kopii roboczej},  label=DoNothingStrategy]{include/src/strategyDoNothing.java} 

\subsection{Powiadomienia}

BuildCity oferuje dwa sposoby bezpośrednich powiadomień - komunikator Gadu-Gadu oraz poczta e-mail. Numery GG oraz adresy pocztowe osób zainteresowanych wynikiem integracji można określić w poszczególnych planach.

Za realizację powyższego wymagania odpowiadają odpowiednio moduły: \textbf{buildcity-notifier-gg}, \textbf{buildcity-notifier-mail}. Do implementacji mechanizmu powiadamiania zastosowany został wzorzec metody szablonowej~\cite{Kerievsky} \ang{Template Method Pattern}.

Powstała abstrakcyjna klasa \tech{AbstractNotifier} z metodą~\ref{notifyEndOfBuild}

\lstinputlisting[caption={Abstrakcyjna metoda realizująca powiadomienia o zakończonej integracji}, label=notifyEndOfBuild]{include/src/notifyEndOfBuild.java} 

Metoda~\ref{notifyEndOfBuild} jest implementowana przez klasy \tech{MailNotifier} oraz \tech{GGNotifier}. Zależności pomiędzy klasami zostały przedstawione na~\rref{UMLCDNotifications} 

\obrazek{\ImgPath/uml_cd_notifiers.png}{Powiadomienia - e-mail i komunikator Gadu-Gadu}{UMLCDNotifications}{.95\textwidth}
\newpage

\subsection{Obsługa komend bota GG}
\label{ggCommandsUml}

Jedną z ciekawszych funkcjonalności jest obsługa komunikatora Gadu-Gadu. Poza standardowymi powiadomieniami, bot Gadu-Gadu nasłuchuje przychodzących wiadomości oraz wykonuje przekazane w ten sposób komendy.

Obsługa komend została zaimplementowana w oparciu o wzorzec komend~\cite{Kerievsky} \ang{Command Pattern}. Wzorzec zakłada stworzenie oddzielnych klas implementujących jeden, spójny interfejs odpowiedzialnych za realizację poszczególnych komend. Obiekty tych klas umieszcza się w mapie \tech{komenda->obiekt wykonawczy}. Po otrzymaniu komendy, z mapy wybierany jest odpowiedni ,,obiekt wykonawczy'' i wywoływana jest na nim metoda udostępniona przez interfejs - zwykle nosi ona nazwę \tech{execute}.

W BuildCity za obsługę bota Gadu-Gadu odpowiada moduł \textbf{buildcity-gg}. Istnieje w nim klasa \tech{GGService}. Klasa realizuje i ukrywa logikę związaną z nawiązaniem  połączenia z serwerami GG, uwierzytelnieniem oraz obsługą wiadomości przychodzących i wychodzących.

W przypadku otrzymania wiadomości przychodzącej, \tech{GGService} deleguje obsługę komendy do klasy \tech{GGCommandsHandler}~\ref{processMessage}. 

\lstinputlisting[caption={Obsługa przychodzącej wiadomości GG - delegacja}, label=processMessage]{include/src/processMessage.java} 

Odpowiedzialnością klasy \tech{GGCommandsHandler} jest obsługa komendy użytkownika i zwrócenie odpowiedniej odpowiedzi. Klasa przechowuje mapowanie odpowiednich komend na obiekty implementujące interfejs \tech{Command}~\ref{command}. 

\lstinputlisting[caption={Interfejs obsługi komend}, label=command]{include/src/command.java} 

W obecnej wersji BuildCity obsługuje tylko jedną komendę jaką jest integracja projektu. Za realizację komendy odpowiada klasa \tech{BuildCommand}~\ref{buildCommand}, która uruchamia integrację projektów, których nazwy zostały przekazane jako parametry komendy.

\lstinputlisting[caption={Realizacja obsługi komendy integracji projektów}, label=buildCommand]{include/src/buildCommand.java}  

Mimo że BuildCity obsługuje obecnie tylko jedną komendę, warto podkreślić, iż zastosowanie opisanego wzorca umożliwia rozszerzenia bota o obsługę dodatkowych komend w bardzo prosty i nieinwazyjny sposób.

Zależności pomiędzy klasami realizującymi obsługę komend bota Gadu-Gadu zostały zaprezentowane na~\rref{UMLCDGGCommands} 
\obrazek{\ImgPath/uml_cd_gg_commands.png}{Obsługa komend bota GG}{UMLCDGGCommands}{.95\textwidth}
\newpage

\subsection{Obsługa systemu kontroli wersji}

Jedną z kluczowych funkcjonalności wymaganych do przeprowadzenia integracji projektu jest obsługa repozytorium kodu. Za realizację wymagania odpowiada moduł \textbf{buildcity-scm}.  Operacje związane z obsługą zdalnego repozytorium Subversion oraz lokalnej kopii roboczej zostały udostępnione przez interfejs \tech{SubversionService}~\ref{subversionService}.

\lstinputlisting[caption={Interfejs do obsługi repozytorium SVN}, label=subversionService]{include/src/subversionService.java}  

Implementacja interfejsu zawarta jest w klasie \tech{SubversionServiceImpl}. Jednym z ciekawszych elementów klasy jest metoda pobierająca świeżą kopię roboczą~\ref{checkout}.

\lstinputlisting[caption={Metoda pobierająca świeżą kopię roboczą}, label=checkout]{include/src/checkout.java} 

Pobranie kopii roboczej wymaga podania dużej ilości parametrów, m.in. protokołu, adresu serwera, portu, rewizji itd. W związku z tym, zastosowany został wzorzec kompozytu \ang{Composite Pattern}, polegający na zgrupowaniu bezpośrednio związanych ze sobą parametrów w pewien kompozyt umożliwiający przekazywanie ich razem pomiędzy poszczególnymi elementami aplikacji. Kompozytem jest klasa \tech{SVNCheckoutParameters}.

Zależności pomiędzy poszczególnymi klasami realizującymi obsługę repozytorium SVN zostały zobrazowane na~\rref{UMLSVN}

\obrazek{\ImgPath/uml_cd_scm.png}{Obsługa systemu kontroli wersji (SVN)}{UMLSVN}{.95\textwidth}

\newpage
\section{Rozwiązania napotkanych problemów}
\subsection{Maven Invoker}
Jednym z pierwszym problemów, jaki autor napotkał podczas implementacji była obsługa Mavena z poziomu kodu Javy. Początkowo zakładano, że użytkownik BuildCity będzie zmuszony do podania na etapie konfiguracji ścieżki systemowej do katalogu, w którym zainstalowany jest Maven. BuildCity miało wówczas wywoływać Mavena jako oddzielny proces systemowy, korzystając z jego skryptów uruchomieniowych \tech{mvn.bat} i \tech{mvn.sh}. W trakcie ewaluowania tego rozwiązania okazało się, że rodzi to szereg komplikacji związanych z przechwytywaniem strumienia wyjściowego, parsowaniem logów, wykrywaniem statusu w jakim proces zakończył swoją pracę na różnych systemach operacyjnych, na których potencjalnie mogłoby pracować BuildCity.

Znacznie lepszym i łatwiejszym sposobem okazało się skorzystanie z projektu Maven Invoker~\cite{MavenInvoker}, oferującego API Mavena dla języka Java. Do zależności projektowych w pliku \tech{pom.xml} należało dodać:

\begin{logs}
<dependency>
	<groupId>org.apache.maven.shared</groupId>
	<artifactId>maven-invoker</artifactId>
	<version>2.0.11</version>
</dependency>
\end{logs}

Jako, że Maven Invoker jest biblioteką napisaną w języku Java, rozwiązanie to jest całkowicie niezależne od systemu operacyjnego. Za budowanie projektów Mavenowych odpowiada moduł \textbf{buildcity-buider-maven2}, a większość logiki związanej z tą funkcjonalnością zrealizowana została w klasie \tech{MavenBuilderService}. Kod korzysta z oferowanego przez Maven Invokera API w sposób jasny i czytelny. Warto zauważyć, że podczas uruchamiania biblioteka poszukuje katalogu instalacyjnego Mavena w oparciu o zmienną systemową \tech{M2\_HOME}. BuildCity wymaga więc, aby na maszynie integracyjnej Maven był zainstalowany, a wspomniana zmienna systemowa była zdefiniowana.

\subsection{Bot GG}
Prace nad stworzeniem bota Gadu-Gadu rozpoczęły się od poszukiwania biblioteki dla języka Java implementującej protokół GG. Wybrana została biblioteka JGGApi~\cite{jggapi}, która mimo, iż nie jest już rozwijana, to działa bez zarzutu. Do API oferowanego przez bibliotekę został stworzony adapter udostępniający dla pozostałych modułów BuildCity jedynie potrzebne i~wymagane metody w interfejsie \tech{GGService.java}:

Podstawowym zadaniem bota jest wysyłanie wiadomości do zdefiniowanych użytkowników. Służy do tego metoda \tech{sendMessage}~\ref{GGServiceSendMessage}

\lstinputlisting[caption={Metoda wysyłająca wiadomości do użytkowników Gadu-Gadu},  label=GGServiceSendMessage]{include/src/GGServiceSendMessage.java}

Bot obsługuje również wiadomości przychodzące, o których więcej można przeczytać w rozdziałach ~\ref{ggCommandsUml} oraz~\ref{ggCommandUserGuide}.

\chapter{BuildCity -- wdrożenie i konserwacja projektu}

W niniejszym rozdziale zawarte będą wszystkie informacje istotne z punktu widzenia osoby, która chciałaby w przyszłości rozwijać projekt BuildCity. Opisane będą wszystkie czynności, jakie należy wykonać, aby pobrać kod z repozytorium, zapoznać się ze strukturą projektu, wybudować oraz uruchomić aplikację.

\section{Repozytorium kodu}

Kod źródłowy aplikacji BuildCity znajduje się repozytorium SVN\footnote{http://code.google.com/p/buildcity/source/browse/svn/trunk/buildcity}. Domyślnie, dostęp do repozytorium jest otwarty w trybie tylko do odczytu. W celu wprowadzania zmian do repozytorium potrzebne jest założenie konta, o co najlepiej zwrócić się do autora tej pracy.

Do pobrania projektu potrzebny jest dowolny klient SVN. W celu pobrania własnej kopii roboczej kodu należy wykonać komendę:
\begin{logs}
svn co http://code.google.com/p/buildcity/source/browse/svn/trunk/buildcity
\end{logs}

Po wykonaniu komendy rozpocznie się pobieranie źródeł aplikacji. Po chwili wszystko, co potrzebne pojawi się w katalogu \tech{buildcity}.

\section{Budowanie projektu}

Od początkowej fazy, projekt BuildCity był tworzony i budowany w oparciu o Mavena. Struktura projektu, rozmieszczenie poszczególnych folderów jest zgodne ze standardem proponowanym przez Mavena~\cite{MavenLayout}. W głównym katalogu projektu znajduje się plik \tech{pom.xml} zawierający informacje wspólne dla każdego modułu. Zdefiniowane tu są przede wszystkim: lokalizacja repozytorium kodu, wersje bibliotek oraz lokalizację ich repozytoriów. 

Aby wybudować projekt i otrzymać wynikowe pliki \tech{*.jar} należy w głównym katalogu projektu wykonać standardową komendę Mavena: \tech{mvn clean install}

Jeśli proces budowania projektu wykonywany jest po raz pierwszy, może on potrwać dość długo (kilkanaście minut). Maven budując każdy moduł aplikacji sprawdza, czy w jego lokalnym repozytorium znajdują się biblioteki niezbędne do kompilacji i uruchomienia projektu. Jeśli stwierdzi ich brak, pobiera je z Internetu, co w takim wypadku znacznie wydłuża proces budowania.

Maven powinien zakończyć swoją pracę komunikatem:

\begin{logs}
[INFO] 
[INFO] -------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] -------------------------------------------------------------
[INFO] buildcity-0.1.0-SNAPSHOT ................... SUCCESS [2.500s]
[INFO] buildcity-core-0.1.0-SNAPSHOT .............. SUCCESS [8.266s]
[INFO] buildcity-scm-0.1.0-SNAPSHOT ............... SUCCESS [1.453s]
[INFO] buildcity-builder-maven2-0.1.0-SNAPSHOT .... SUCCESS [3.015s]
[INFO] buildcity-charts-0.1.0-SNAPSHOT ............ SUCCESS [2.110s]
[INFO] buildcity-gg-0.1.0-SNAPSHOT ................ SUCCESS [2.672s]
[INFO] buildcity-notifier-gg-0.1.0-SNAPSHOT ....... SUCCESS [1.453s]
[INFO] buildcity-notifier-mail-0.1.0-SNAPSHOT ..... SUCCESS [2.828s]
[INFO] buildcity-notifier-rss-0.1.0-SNAPSHOT ...... SUCCESS [1.719s]
[INFO] buildcity-scheduler-0.1.0-SNAPSHOT ......... SUCCESS [9.265s]
[INFO] buildcity-web-0.1.0-SNAPSHOT ............... SUCCESS [35.156s]
[INFO] -------------------------------------------------------------
[INFO] -------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] -------------------------------------------------------------
[INFO] Total time: 1 minute 10 seconds
[INFO] Finished at: Wed May 05 19:56:38 CEST 2010
[INFO] Final Memory: 27M/63M
[INFO] -------------------------------------------------------------
\end{logs}



\section{Uruchomienie}

Zbudowany projekt jest gotowy do uruchomienia i nie wymaga instalacji czy uruchamiania żadnego dodatkowego oprogramowania. W domyślnej konfiguracji BuildCity korzysta z wbudowanej bazy danych H2, która tworzy potrzebne jej pliki w katalogu domowym użytkownika. Pliki mają prefiks \tech{buildcity}. Dzięki takiemu rozwiązaniu uruchomienie aplikacji jest proste i nie wymaga żadnej konfiguracji połączenia z bazą danych. Jednocześnie, wszelkie dane wprowadzone do buildcity przetrwają restart aplikacji.

Aby uruchomić aplikację w domyślnym trybie należy przejść do modułu interfejsu użytkownika, czyli \textbf{buildcity-web} i wykonać: \tech{mvn jetty:run}

Powyższa komenda uruchomi wcześniej wybudowaną aplikację na serwerze Jetty będącego wtyczką do Mavena. Definicja i konfiguracja tej wtyczki znajduje się w pliku \tech{pom.xml} modułu buildcity-web. W domyślnej konfiguracji serwer Jetty startuje i nasłuchuje na porcie 8080. Serwer jest gotowy do pracy gdy w konsoli pojawi się:

\begin{logs}
2010-05-05 20:05:55 com.sun.faces.config.ConfigureListener contextInitialized
INFO: Initializing Mojarra (1.2\_12-b01-FCS) for context '/buildcity-web'
2010-05-05 20:05:57.255::INFO:  Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
[INFO] Starting scanner at interval of 5 seconds.
\end{logs}

Po uruchomieniu wystarczy odwiedzić adres:
\begin{logs}
http://localhost:8080/buildcity-web
\end{logs}

Jeśli w przeglądarce pojawi się ekran podobny tego na~\rref{buildcity-startpage}, oznacza to, że aplikacja została poprawnie pobrana z repozytorium, wybudowana, uruchomiona i jest gotowa do pracy i testów.
\obrazek{\ImgPath/buildcity_startpage.png}{BuildCity -- ekran po pierwszym uruchomieniu}{buildcity-startpage}{.95\textwidth}

\chapter{BuildCity -- dokumentacja użytkownika}

W rozdziale~\ref{wordcountertestproject} opisany został testowy projekt stworzony na potrzeby niniejszej pracy. Projekt ten, w swoim założeniu reprezentuje typowy projekt wielomodułowy, budowany przez Mavena. 

Przyjęto założenie, że nad tym projektem pracuje kilka osób, niekoniecznie w tej samej lokalizacji geograficznej. W takiej sytuacji bardzo łatwo jest wprowadzić błąd, który zostanie wykryty dopiero po jakimś czasu i to najprawdopodobniej przez innego programistę. W niniejszym rozdziale opisany zostanie typowy przypadek użycia dla aplikacji BuildCity. 

Na początku, stworzony zostanie nowy plan, monitorujący zmiany w projekcie \tp. Skonfigurowane zostaną powiadomienia przez komunikator Gadu-Gadu oraz e-mailowe.

Następnie, do jednego z modułów projektu wprowadzona zostanie pozornie mała zmiana, która jednak spowoduje błąd w teście integracyjnym znajdującym się w innym module aplikacji. Sytuacja taka jest szczególnie często spotykana, gdy programista wprowadził zmianę do repozytorium nie zadając sobie wcześniej trudu uruchomienia testów we wszystkich modułach aplikacji. Przy odrobinie szczęścia zmiana taka zostałaby zauważona przez programistę pracującym nad wspomnianym modułem. Problem robi się poważniejszy, gdy nad danym modułem nikt nie pracuje, a zespół nie ma w zwyczaju częstego budowania całej aplikacji (wraz z uruchomieniem testów). 

Aby wyeliminować takie sytuacje, pokazane zostanie w jak krótkim czasie BuildCity wykryje taką zmianę i powiadomi zdefiniowaną liczbę osób o tym, że integracja projektu po ostatniej zmianie się nie powiodła. Następnie pokazane będzie, jak przeglądając ostatnią aktywność i powiązane z nią zmiany można stwierdzić w czym leży problem i który test nie został spełniony. Wytypowana też będzie osoba odpowiedzialna za wprowadzenie destabilizującego kodu do repozytorium. Po wdrożeniu poprawki użyty zostanie bot komunikatora Gadu-Gadu, któremu wydana zostanie komenda przeprowadzenia natychmiastowej integracji projektu. O sukcesie wykonanej integracji BuildCity ponownie powiadomi wszystkich użytkowników.

Ostatnim etapem będzie obejrzenie kanału RSS publikującego informacje o aktywnościach w obszarze każdego z monitorowanych projektów.

\section{Projekt testowy}
\label{wordcountertestproject}
Na potrzeby porównania istniejących narzędzi wspierających praktykę ciągłej integracji oraz przedstawienia możliwości przykładowej aplikacji powstałej w ramach niniejszej pracy, stworzony został przykładowy projekt, który będzie podlegał integracji wykonywanej przez wszystkie te narzędzia. \tp to prosta aplikacja służąca do wyszukiwania i zliczania ilości wystąpień słowa w tekście, wykorzystująca algorytm Knutha--Morrisa--Pratta \cite{KMPAlrgorithm}.

\tp składa się z trzech modułów:
\begin{itemize}
	\item \textbf{wordcounter-core}, zawiera klasy realizujące analizę wprowadzonego tekstu i zwracające listę słów wraz z liczbą ich wystąpień jako pojedynczych słów oraz w innych słowach 
	\item \textbf{wordcounter-web}, zawiera warstwę graficznego interfejsu użytkownika dla przeglądarek internetowych
	\item \textbf{wordcounter-cmd}, zawiera konsolowy interfejs użytkownika umożliwiający wczytanie i analizowanie pliku tekstowego oraz wyświetlanie wyniku na konsolę
\end{itemize}

\tp można pobrać z ogólnodostępnego repozytorium SVN\footnote{http://code.google.com/p/buildcity/source/browse/svn/trunk/wordcounter} i wybudować standardową komendą Mavena: \tech{mvn clean install}~\cite{mvncleaninstall}. 

Z aplikacji można korzystać poprzez dwa interfejsy: konsola oraz przeglądarka internetowa. Z punktu widzenia użycia projektu i dokonywania w nim późniejszych zmian na potrzeby niniejszej pracy, istotniejszy jest interfejs dla przeglądarki internetowej. Najszybszym sposobem uruchomienia aplikacji po jej wcześniejszym wybudowaniu jest wykonanie w katalogu \tech{wordcounter-web} komendy:
\tech{mvn jetty:run}. Po pojawieniu się 
\begin{logs}
2010-05-09 21:07:06.968:INFO::Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
\end{logs}
można odwiedzić adres \tech{http://localhost:8080/wordcounter-web}.

Interfejs graficzny jest bardzo prosty i umożliwia wprowadzenie dowolnego tekstu do analizy~(\rref{WordcounterStartpage}).
\obrazek{\ImgPath/wordcounter_startpage.png}{WordCounter -- ekran startowy}{WordcounterStartpage}{.95\textwidth}

Po wpisaniu dowolnego tekstu, np. \textit{,,To jest test testujący algorytm KMP''} i kliknięciu ,,Analyze'' pojawiają się wyniki (~\rref{WordcounterResults}). Zgodnie z oczekiwaniami, każde ze słów wystąpiło w tekście dokładnie raz. Ponadto, słowo \textit{,,test''} wystąpiło też dokładnie raz wewnątrz innego słowa (\textit{,,testujący''}).

\obrazek{\ImgPath/wordcounter_results.png}{WordCounter -- wyniki analizy}{WordcounterResults}{.95\textwidth}

\subsection*{Testy}

\tp~posiada zestaw testów weryfikujących zarówno prawidłowe działanie implementacji algorytmu KMP, jak też poprawność samego interfejsu użytkownika. Zgodnie z konwencją Mavena, testy są zlokalizowane w poszczególnych modułach w folderach \tech{src/test/java}~\cite{MavenLayout}. Dla przykładu, moduł \textbf{wordcounter-core} zawiera test \tech{\textbf{WordCounterTest}}, weryfikujący czy wprowadzony tekst jest poprawnie analizowany. W przypadku wprowadzenia błędnej zmiany w implementacji algorytmu, istnieje bardzo duża szansa, że test zwróci na to uwagę programisty.

Na uwagę zasługują automatyczne testy interfejsu użytkownika. W module \textbf{wordcounter-web} znajduje się test \tech{\textbf{TestAnalyze}}. Test posiada następujący scenariusz:
\begin{enumerate}
	\item wejdź na główną stronę aplikacji
	\item zweryfikuj czy na stronie znajduje się formularz z polem tekstowym
	\item wprowadź do pola zdefiniowany tekst
	\item kliknij przycisk ,,Analizuj''
	\item zweryfikuj, czy zwrócona została strona z wynikami analizy
	\item zweryfikuj, czy na stronie znajduje się tabela zawierająca oczekiwane wyniki
\end{enumerate}

W przypadku dokonania jakiejkolwiek modyfikacji, która spowoduje, że wyniki analizy będą inne od oczekiwanych, test będzie kończył się błędem. 


\section{Definiowanie pierwszego planu}

Świeżo wybudowana aplikacja nie posiada żadnych projektów do monitorowania. Wobec tego, należy rozpocząć od zdefiniowania pierwszego planu. W menu \tech{Konfiguracja -> Zarządzanie planami} można stworzyć nowy plan. Aplikacja BuildCity potrzebuje następujących parametrów dla planu:

		\begin{center}
		   \begin{tabular}{ | l | p{8cm} |}
			   \hline
                Pole & Opis/Uwagi \\ \hline
                Nazwa & Unikatowa nazwa planu \\ \hline
				Cron & Wyrażenie cron definiujące częstotliwość sprawdzania zmian w monitorowanym projekcie~\cite{quartzcron} \\ \hline
				URL do SVN & Lokalizacja kodu źródłowego projektu, który ma być monitorowany \\ \hline
				Checkout do & Lokalna ścieżka, do której ma być pobrany kod monitorowanego projektu \\ \hline
				Build command & Komenda \ang{goals} dla mavena. Uwaga -- należy podać same cele, bez 'mvn'! \\ \hline
				Wymuś 'czysty build' & Wybranie tej opcji oznacza, że co ustalony interwał czasowy projekt 
				będzie budowany od początku, nawet jeśli nie pojawiła się w nim żadna zmiana. \\ \hline
				Powiadom adresy e-mail & Można podać kilka adresów, oddzielając je średnikiem (\tech{;}) \\ \hline
				Powiadom numery gg & Można podać kilka numerów, oddzielając je średnikiem  (\tech{;}) \\ \hline
            \end{tabular}
		\end{center}

W ekranie do definiowania nowego planu podajemy niezbędne dane:

		\begin{center}
		   \begin{tabular}{ | l | p{8cm} |}
			    \hline
                Pole & Wartość \\ \hline
                Nazwa & \tp \\ \hline
				Cron & 0 0/1 * * * ? \\ \hline
				URL do SVN & \tech{http://buildcity.googlecode.com/ svn/trunk/wordcounter/} \\ \hline
				Checkout do & \tech{c:/test} \\ \hline
				Build command & \tech{clean install} \\ \hline
				Wymuś 'czysty build' & Nie \\ \hline
				Powiadom adresy e-mail & \tech{mateusz.grzechocinski@gmail.com} \\ \hline
				Powiadom numery gg & 1002098 \\ \hline
            \end{tabular}
		\end{center}

\section{Pierwsza integracja}
Zapisanie wyżej zdefiniowanego planu spowoduje wykonanie pierwszej, przymusowej integracji. Informacja o tym pojawia się na stronie startowej, co widać na ~\rref{buildcity-fisrt-activity}.
\obrazek{\ImgPath/buildcity_first_activity.png}{BuildCity -- pierwsza integracja po zdefiniowaniu nowego planu}{buildcity-fisrt-activity}{.65\textwidth}

Projekt \tp w obecnej fazie buduje się poprawnie, więc po kilku chwilach integracja kończy się sukcesem. Zgodnie z definicją planu, BuildCity informuje o tym fakcie poprzez komunikator Gadu-Gadu~(\rref{buildcity-first-gg-notification}) oraz stosownym e-mailem~(\rref{buildcity-first-mail-notification}).

\obrazek{\ImgPath/buildcity_first_gg_notification.png}{Powiadomienie o zakończeniu integracji (komunikator Gagu-gadu)}{buildcity-first-gg-notification}{.55\textwidth}
\obrazek{\ImgPath/buildcity_first_mail_notification.png}{Powiadomienie o zakończeniu integracji (e-mail)}{buildcity-first-mail-notification}{.95\textwidth}

\newpage
\section{Wprowadzenie ,,złej'' zmiany}

W projekcie \tp istnieje klasa \tech{WordCounter} posiadająca jedną metodę statyczną \tech{List<WordObject> analyze(String toAnalyze)}. Jedną z metod wywoływanych wewnątrz niej jest poniższa, zliczająca ilość wystąpień słowa w tekście.

\lstinputlisting[caption={Metoda zliczająca wystąpienia słów w tekście},  label=countAloneOccurrences]{include/src/countAloneOccurrences.java}
 
Metoda ta parsuje wejściowy napis według białych znaków i zwraca mapę \tech{napis->obiekt}. W obiekcie zapisana jest liczba jaką dany napis występował w tekście samodzielnie.
W module \textbf{wordcounter-web} znajdują się testy weryfikujące poprawność działania algorytmu względem tekstu, w którym słowa rozdzielone są spacjami.

\lstinputlisting[caption={Przykładowy test weryfikujący poprawność działania algorytmu względem pliku słów rozdzielonych spacjami}, label=shouldIncrementInOtherCounter]{include/src/shouldIncrementInOtherCounter.java}


W module \textbf{wordcounter-web} znajduje się kompleksowy test integracyjny, weryfikujący, czy wprowadzony tekst \textbf{zawierający również znaki nowej linii} zostanie poprawnie zanalizowany, a wyniki pojawią się na stronie internetowej.

\lstinputlisting[caption={Przykładowy test integracyjny}, label=shouldRedirectToPageWithProperResults]{include/src/shouldRedirectToPageWithProperResults.java}

Zakłada się, że programista pracujący nad modułem \tech{webcounter-core} i nie znający wyrażeń regularnych, stwierdza, iż zmieni implementację metody~\ref{countAloneOccurrences} w taki sposób, aby parsować wejściowy napis według spacji. Zmienia więc linię kodu:

\lstinputlisting[caption={Kod przed zmianą}, label=before]{include/src/before.java}

na 

\newpage
\lstinputlisting[caption={Kod po zmianie}, label=after]{include/src/after.java}

Programista pracuje nad swoim modułem, więc po wykonaniu zmiany uruchamia testy dla tego modułu. Ponieważ testy znajdująca się w jego module weryfikują poprawność działania algorytmu tylko dla napisów rozdzielonych spacjami, programista po chwili stwierdza, że jego zmiana (pozornie) nie spowodowała niczego złego. Kończy swoją aktywność wprowadzeniem zmiany do głównego repozytorium kodu.

\section{Reakcja BuildCity}

BuildCity monitoruje projekt ze zdefiniowaną częstotliwością. Zmiana zostaje wykryta zaraz po wprowadzenia jej przez programistę. Rozpoczyna się proces integracji projektu, która po chwili kończy się niepowodzeniem. Zdefiniowan grupa osób otrzymuje powiadomienia przez komunikator Gadu-Gadu~\rref{buildcity-activity-failed-gg} oraz pocztę e-mail~\rref{buildcity-activity-failed-email}.
\obrazek{\ImgPath/buildcity_reaction_failed_gg_notification.png}{BuildCity -- powiadomienie o błędzie integracji (komunikator Gadu-Gadu)}{buildcity-activity-failed-gg}{.85\textwidth}
\obrazek{\ImgPath/buildcity_reaction_failed_mail_notification.png}{BuildCity -- powiadomienie o błędzie integracji (poczta e-mail)}{buildcity-activity-failed-email}{.95\textwidth}

\section{Diagnoza problemu}

Do zdiagnozowania zaistniałego problemu służy ekran aktywności. Po wejściu na główną stronę BuildCity widać, że integracja projektu \tech{WordCounter} zakończyła się błędem~(\rref{buildcity-reaction-failed}). 
\obrazek{\ImgPath/buildcity_reaction_failed.png}{BuildCity -- informacja, że ostatnia integracja zakończyła się błędem}{buildcity-reaction-failed}{.55\textwidth}

Po kliknięciu w \tech{WordCounter-2} BuildCity przechodzi do ekranu ostatniej integracji~\ref{buildcity-reaction-failed-activity}. Na ekranie, odpowiednim kolorem prezentowany jest status ostatniej integracji. Wyświetlany jest też czas rozpoczęcia i zakończenia integracji oraz nazwa planu. Na uwagę zasługują informacje znajdujące się po prawej stronie ekranu. Wyświetlana jest tam lista zmian wykryta przez BuildCity, które spowodowały wzbudzenie integracji. Można dzięki temu w łatwy i szybki sposób ocenić czyja zmiana zdestabilizowała kod. Dostępna jest nazwa autora zmiany, komentarz do zmiany oraz lista plików, jakie zostały zmienione (\tech{A} -- dodane/\tech{D} -- usunięte/\tech{M} -- zmodyfikowane). Ponadto, dla jeszcze lepszej diagnozy problemu użytkownik ma możliwość rozwinięcia panelu z logami z procesu budowania monitorowanego projektu. 
\obrazek{\ImgPath/buildcity_reaction_failed_activity.png}{BuildCity -- ekran ostatniej integracji zakończonej błędem}{buildcity-reaction-failed-activity}{.95\textwidth}

Z zapisanych przez buildCity logów widać jasno, że powodem błędu integracji był niespełniony test \tech{shouldRedirectToPageWithProperResults}. Test ten znajduje się w klasie \tech{net.grzechocinski.TestAnalyze} w module \tech{wordcounter-web}.
\obrazek{\ImgPath/buildcity_reaction_failed_logs.png}{BuildCity -- logi z procesu integracji i niespełniony test w module wordcounter-web}{buildcity-reaction-failed-activity}{.95\textwidth}

\section{Wprowadzenie poprawki}

Po zdiagnozowaniu problemu i wprowadzeniu poprawki do repozytorium kodu, zespół zazwyczaj nie powinien czekać na kolejną reakcję narzędzia do ciągłej integracji. Oczekiwanie na reakcję po wprowadzeniu każdej poprawki stabilizującej kod wiązałoby się z dużą stratą czasu. Do tego celu powstał mechanizm wzbudzania integracji ,,na żądanie''. Istnieją dwa sposoby na zlecenie BuildCity natychmiastowej integracji wybranego projektu:
\begin{itemize}
	\item Kliknięcie przycisku ,,Uruchom teraz'' znajdującego się przy każdym monitorowanym projekcie na stronie głównej BuildCity (zielona strzałka).
	\item Wydanie komendy botowi Gadu-Gadu
\end{itemize}

\section{Bot Gadu-Gadu -- wydawanie komend}
\label{ggCommandUserGuide}

Poza standardową rolą, jaką jest powiadamianie zdefiniowanej listy osób o zakończeniu danej integracji, bot Gadu-Gadu obsługuje też komendy przychodzące od użytkowników aplikacji. Format wydawanych komend jest następujący:

\begin{verbatim}
<command>: <parameter1>,<parameter2>,<parameter3>...<parameterN>
\end{verbatim}

Bot dokonuje walidacji komend i zawsze odpowiada użytkownikowi, nawet gdy komenda jest niezrozumiała~(\rref{buildcity-gg-unknown-command})
\obrazek{\ImgPath/buildcity_gg_unknown_command.png}{Bot GG -- walidacja komend}{buildcity-gg-unknown-command}{.65\textwidth}

W podstawowej wersji, bot obsługuje jedną komendę -- integracja projektu na żądanie. Obsługa komend została zaimlementowana w taki sposób, aby dodanie nowych komend było możliwie najłatwiejsze. 
Aby zlecić BuildCity wykonanie integracji wybranego projektu, wystarczy z dowolnego klienta Gadu-Gadu napisać do bota następującą komendę:
\begin{verbatim}
build: <nazwa_projektu>
\end{verbatim}

Ponieważ zespół po wprowadzeniu poprawki do projektu WordCounter chce jak najszybciej dowiedzieć się o jej skutkach, jeden z użytkowników może wydać botowi Gadu-Gadu komendę, jak na~\rref{buildcity-gg-on-demand}
\obrazek{\ImgPath/buildcity_jobfired.png}{Bot GG -- integracja ,,na żądanie''}{buildcity-gg-on-demand}{.95\textwidth}

Po chwili okazuje się, że poprawka faktycznie pomogła. Ponownie, BuildCity informuje o tym za pośrednictwem komunikatora i e-maila.~\ref{buildcity-gg-success}
\obrazek{\ImgPath/buildcity_jobfired_ended_succesfully.png}{BuildCity -- integracja zakończona powodzeniem}{buildcity-gg-success}{.65\textwidth}

Również w oknie aktywności pojawia się stosowna informacja, że kod jest stabilny i spełnia wszystkie dostarczone testy.~\ref{buildcity-activity-success}
\obrazek{\ImgPath/buildcity_reaction_successful_activity.png}{BuildCity -- integracja zakończona powodzeniem}{buildcity-activity-success}{.45\textwidth}

\section{Kanał RSS}

Ostatnią funkcjonalnością są kanały RSS. Dla każdego monitorowanego projektu BuildCity oferuje oddzielny kanał RSS agregujący informacje o wszystkich jego integracjach.
Dla przykładu, w przeglądarce Internet Explorer 8 RSS'y prezentowane są jak na~\ref{buildcity-rss}

\obrazek{\ImgPath/buildcity_rss.png}{BuildCity -- kanał RSS dla projektu \tp}{buildcity-rss}{.95\textwidth}

\chapter{Zastosowanie i wizje rozwoju}

\section{Obecna funkcjonalność}
W chwili zakończenia prac nad BuildCity w ramach niniejszej pracy magisterskiej, aplikacja posiada wersję 1.0 i~uznana jest za wersję stabilną i~możliwą do użycia. Jednocześnie warto zauważyć, że BuildCity powstało jako \textbf{przykładowe} narzędzie, w pełni realizujące \textbf{podstawowe} założenia praktyki ciągłej integracji. Ponadto, pomogło autorowi niniejszej pracy w zrozumieniu zasady działania tego typu aplikacji oraz poznania kilku ciekawych technik oraz bibliotek programistycznych przydatnych do jego codziennej pracy nad innymi projektami komercyjnymi. 

\section{Czysty kod}
Podczas implementacji aplikacji, autor pracy przyłożył bardzo dużą wagę do tego, aby kod był napisany w sposób nowoczesny, czytelny i zgodny z powszechnymi wzorcami programistycznymi. Projekt jest modularny, a wydzielone w projekcie moduły posiadają zwykle tylko jeden abstrakcyjny interfejs, za którym ukryta jest cała złożona logika realizująca pewną funkcjonalność (np. obsługę repozytorium SVN). W skład projektu wchodzą też testy jednostkowe i integracyjne, które na bieżaco weryfikują jego jakość.

Głównym celem jaki przyświecał autorowi było zaimplementowanie całej aplikacji w taki sposób, aby jej rozszerzanie o dodatkowe funkcjonalności było możliwe jak najmniejszym kosztem. Przy implementacji każdego z elementów systemu, brane pod uwagę były możliwości rozszerzenia danego modułu o dodatkowe funkcjonalności. I tak, np. implementacja dodatkowych komend dla bota Gadu-Gadu nie powinna stanowić żadnego problemu. 

Poniżej zdefiniowano listę potencjalnych punktów rozszerzeń BuildCity o funkcjonalności, których obecność sprawiłaby, że aplikacja ta mogłaby z powodzeniem zostać użyta do realnych projektów.
\begin{itemize}
	\item{obsługa repozytorium CVS,}
	\item{obsługa repozytorium SVN wymagających autoryzacji,}
	\item{stworzenie modułu raportowego -- statystyki, wykresy,}
	\item{obsługa narzędzia budującego ANT.}
\end{itemize}

Podczas ewentualnego rozwijania projektu, ciekawym pomysłem może być przeprowadzenie integracji BuildCity w... samym BuildCity. Wybudowana, zainstalowana i skonfigurowana instancja mogłaby monitorować zmiany wprowadzane do publicznego repozytorium kodu BuildCity, wykonywać dostarczone automatyczne testy jednostkowa oraz informować programistów o ewentualnych problemach ze stabilnością kodu.

%-----------------
% Wnioski
%-----------------
\chapter{Wnioski}

Ciągła integracja jest zdaniem autora pracy praktyką zdecydowanie wartą wdrożenia w każdym zespole programistycznym.
Za jej zastosowaniem przemawia stosunkowo niski koszt wdrożenia, zwłaszcza w przypadku wybrania narzędzia darmowego, jak Hudson lub BuildCity. CI niesie ze sobą bardzo dużą liczbę korzyści, zarówno dla zespołu, kadry zarządzającej, jak i samego klienta:
\begin{enumerate}
  \item{Minimalizuje ryzyko, że kod znajdujący się w repozytorium zawiera błędy i wymaga dodatkowej uwagi ze strony zespołu.}
  \item{Gwarantuje szybki dostęp do aplikacji zbudowanej z najświeższego kodu źródłowego.}
  \item{W sposób natychmiastowy zwraca uwagę programistów na ewentualne problemy występujące na maszynie integracyjnej.}
  \item{Jest wyznacznikiem jakości i przesądza jednoznacznie o stabilności kodu znajdującego się w repozytorium kodu, przez co zmniejsza potencjalne konflikty w zespole i niweluje brak odpowiedzialności za wprowadzenie błędnych zmian do projektu}
\end{enumerate} 

Na rynku dostępnych jest obecnie bardzo dużo narzędzi wspierających i~automatyzujących praktykę ciągłej integracji. Większość z nich jest darmowa i może być użyta to zastosowań komercyjnych. Z punktu widzenia firmy czy organizacji, jedynym kosztem jakie trzeba ponieść jest krótki czas na skonfigurowanie środowiska zbliżonego do produkcyjnego oraz zainstalowanie na nim i skonfigurowanie odpowiedniego narzędzia. Wysiłek ten jest jednak z całą pewnością warty podjęcia. Spadek liczby błędów pojawiających się w produkowanym oprogramowaniu, a także pozytywny wpływ na zespół będzie możliwy do zauważenia w bardzo krótkim czasie. Ponadto, aby jeszcze bardziej skupić uwagę programistów, warto wyposażyć zespół np. w lampy sygnalizujące aktualną kondycję aplikacji budowanej na maszynie integracyjnej.

Autor niniejszej pracy pracuje w zespole programistów stosującym praktykę Ciągłej Integracji od niemal dwóch lat. Narzędziem wspierającym ten proces jest omawiany w rozdziale \ref{atlassianbamboochapter} Atlassian Bamboo. Podczas niespełna dwóch lat pracy programistycznej w kilkuosobowych zespołach, autor często przekonywał się o niewątpliwych zaletach stosowania Ciągłej Integracji i jest przez to absolutnym zwolennikiem takiego podejścia. 

Dzięki niniejszej pracy, autor pogłębił swoją wiedzę na temat zwinnych metodyk prowadzenia projektów informatycznych, które zdecydowanie popiera i stosuje podczas swojej pracy zawodowej. Zgłębił zasadę działania popularnych narzędzi wspierających praktykę CI oraz poznał kilka nowych, ciekawych bibliotek programistycznych, które ułatwią Mu implementację zadanych komponentów w produkowanych systemach informatycznych.

Autor wyraża też nadzieję, że stworzone w niniejszej pracy narzędzie BuildCity będzie mogło w przyszłości być rozwijane przez zainteresowane podobnymi tematami osoby, które chciałyby na bazie tego projektu stworzyć bardziej rozbudowany i funkcjonalny produkt. Między innymi z tego powodu autor pracy przyłożył bardzo duże znaczenie do jakości napisanego kodu, jego czytelności, pokrycia testami automatycznymi oraz łatwości w jego utrzymaniu.

\input{include/tex/bibliografia.tex}
\end{document}
%+++ END +++
